PageSourceSearch

https://www.defensa.gob.es/resources/scripts/unitegallery.js

js defensa.gob.es collected 2026-09-24 08:32:15 UTC 588,488 bytes, 25,135 lines download raw bytes

1// Unite Gallery, Version: 1.7.45, released 27 Feb 2017 
2
3
4
5/**
6 * write something to debug line
7 */
8function debugLine(html,addRandom, addHtml){
9	
10	if(html === true)
11		html = "true";
12	
13	if(html === false)
14		html = "false";		
15	
16	var output = html;
17	
18	if(typeof html == "object"){
19		output = "";
20		for(name in html){
21			var value = html[name];
22			output += " " + name + ": " + value;
23		}
24	}
25	
26	if(addRandom == true && !addHtml)
27		output += " " + Math.random();	
28	
29	if(addHtml == true){
30		var objLine = jQuery("#debug_line");
31		objLine.width(200);
32		
33		if(objLine.height() >= 500)
34			objLine.html("");
35		
36		var currentHtml = objLine.html();
37		output = currentHtml + "<br> -------------- <br>" + output;		
38	}
39	
40	jQuery("#debug_line").show().html(output);		
41		
42}
43
44/**
45 * 
46 * debug side some object
47 */
48function debugSide(obj){
49	
50	var html = "";
51	for(name in obj){
52		var value = obj[name];
53		html += name+" : " + value + "<br>";		
54	}
55	
56	jQuery("#debug_side").show().html(html);
57
58}
59
60
61/**
62 * output some string to console
63 */
64function trace(str){
65	
66	if(typeof console != "undefined")
67		console.log(str);
68
69}
70
71
72
73
74/** -------------- UgFunctions class ---------------------*/
75
76function UGFunctions(){
77	
78	var g_browserPrefix = null;	
79	var t = this;
80	var g_temp = {
81		starTime:0,
82		arrThemes:[],
83		isTouchDevice:-1,
84		isRgbaSupported: -1,
85		timeCache:{},
86		dataCache:{},
87		lastEventType:"",		//for validate touchstart click
88		lastEventTime:0,
89		lastTouchStartElement:null,
90		touchThreshold:700,
91		handle: null			//interval handle
92	};
93	
94	this.debugVar = "";
95
96	this.z__________FULL_SCREEN___________ = function(){}
97	
98	
99	
100	/**
101	 * move to full screen mode
102	 * fullscreen ID - the ID of current fullscreen
103	 */
104	this.toFullscreen = function(element, fullscreenID) {
105		  	  
106		  if(element.requestFullscreen) {
107		    element.requestFullscreen();
108		  } else if(element.mozRequestFullScreen) {
109		    element.mozRequestFullScreen();
110		  } else if(element.webkitRequestFullscreen) {
111		    element.webkitRequestFullscreen(); 
112		  } else if(element.msRequestFullscreen) {
113			    element.msRequestFullscreen(); 
114		  } else{
115			  return(false);
116		  }
117		  
118		  return(true);
119	}	
120	
121	
122	/**
123	 * exit full screen mode
124	 * return if operation success (or if fullscreen mode supported)
125	 */
126	this.exitFullscreen = function() {
127		  if(t.isFullScreen() == false)
128			  return(false);
129			  
130		  if(document.exitFullscreen) {
131		    document.exitFullscreen();
132
133		  } else if(document.cancelFullScreen) {
134			    document.cancelFullScreen();
135		    
136		  } else if(document.mozCancelFullScreen) {
137		    document.mozCancelFullScreen();
138		    
139		  } else if(document.webkitExitFullscreen) {
140		    document.webkitExitFullscreen();
141		    
142		  } else if(document.msExitFullscreen) {
143			    document.msExitFullscreen();
144			    
145		  }else{
146			  return(false);
147		  }
148		  
149		  return(true);
150	}	
151
152	/**
153	 * cross browser attach even function
154	 */
155	function addEvent(evnt, elem, func) {
156		   if (elem.addEventListener)  // W3C DOM
157		      elem.addEventListener(evnt,func,false);
158		   else if (elem.attachEvent) { // IE DOM
159		      elem.attachEvent("on"+evnt, func);
160		   }
161		   else { // No much to do
162		      elem[evnt] = func;
163		   }
164	}
165	
166	
167	/**
168	 * add fullscreen event to some function
169	 */
170	this.addFullScreenChangeEvent = function(func){
171		
172		if(document["webkitCancelFullScreen"])
173			addEvent("webkitfullscreenchange",document,func);
174		else if(document["msExitFullscreen"])
175			addEvent("MSFullscreenChange",document,func);
176		else if(document["mozCancelFullScreen"])
177			addEvent("mozfullscreenchange",document,func);
178		else
179			addEvent("fullscreenchange",document,func);
180	}
181	
182	
183	/**
184	 * destroy the full screen change event
185	 */
186	this.destroyFullScreenChangeEvent = function(){
187		
188		jQuery(document).unbind("fullscreenChange");
189		jQuery(document).unbind("mozfullscreenchange");
190		jQuery(document).unbind("webkitfullscreenchange");
191		jQuery(document).unbind("MSFullscreenChange");
192	}
193	
194	
195	/**
196	 * get the fullscreen element
197	 */
198	this.getFullScreenElement = function(){
199		
200		var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
201		
202		return(fullscreenElement);
203	}
204
205	/**
206	 * return if fullscreen enabled
207	 */
208	this.isFullScreen = function(){
209		
210		var isFullScreen = document.fullscreen || document.mozFullScreen || document.webkitIsFullScreen || document.msFullscreenElement;
211		
212		if(!isFullScreen)
213			isFullScreen = false;
214		else
215			isFullScreen = true;
216		
217		return(isFullScreen);
218	}
219	
220	
221	
222	this.z__________GET_PROPS___________ = function(){}
223	
224	/**
225	 * get browser prefix, can be empty if not detected.
226	 */
227	this.getBrowserPrefix = function(){
228		
229	   if(g_browserPrefix !== null)
230		   return g_browserPrefix;
231				
232	   var arrayOfPrefixes = ['webkit','Moz','ms','O'];
233	   
234	   var div = document.createElement("div");
235	   
236	   for(var index in arrayOfPrefixes){
237		   var prefix = arrayOfPrefixes[index];
238		   
239		   if(prefix+"Transform" in div.style){
240			   prefix = prefix.toLowerCase();
241			   g_browserPrefix = prefix;
242			   return(prefix);
243		   }
244	   }
245	   
246	   g_browserPrefix = "";
247	   return "";
248	}
249	
250	/**
251	 * get image inside parent data by image (find parent and size)
252	 * scaleMode: fit, down, fill, fitvert
253	 */
254	this.getImageInsideParentDataByImage = function(objImage, scaleMode, objPadding){
255		
256		var objParent = objImage.parent();
257		
258		var objOrgSize = t.getImageOriginalSize(objImage);
259		
260		var objData = t.getImageInsideParentData(objParent, objOrgSize.width, objOrgSize.height, scaleMode, objPadding);
261		
262		return(objData);
263	}
264	
265	
266	/**
267	 * get data of image inside parent
268	 * scaleMode: fit, down, fill, fitvert
269	 */
270	this.getImageInsideParentData = function(objParent, originalWidth, originalHeight, scaleMode, objPadding, maxWidth, maxHeight){
271		
272		if(!objPadding)
273			var objPadding = {};
274		
275		var objOutput = {};
276		
277		if(typeof maxWidth === "undefined")
278			var maxWidth = objParent.width();
279		
280		if(typeof maxHeight === "undefined")
281			var maxHeight = objParent.height();
282		
283		if(objPadding.padding_left)
284			maxWidth -= objPadding.padding_left;
285		
286		if(objPadding.padding_right)
287			maxWidth -= objPadding.padding_right;
288		
289		if(objPadding.padding_top)
290			maxHeight -= objPadding.padding_top;
291		
292		if(objPadding.padding_bottom)
293			maxHeight -= objPadding.padding_bottom;
294		
295		var imageWidth = null;
296		var imageHeight = "100%";
297		var imageTop = null;
298		var imageLeft = null;		
299		var style = "display:block;margin:0px auto;";
300		
301		if(originalWidth > 0 && originalHeight > 0){
302			
303			//get image size and position
304			
305			if(scaleMode == "down" && originalWidth < maxWidth && originalHeight < maxHeight){
306			
307				imageHeight = originalHeight;
308				imageWidth = originalWidth;
309				imageLeft = (maxWidth - imageWidth) / 2;
310				imageTop = (maxHeight - imageHeight) / 2;
311				
312			}else if(scaleMode == "fill"){
313				var ratio = originalWidth / originalHeight;
314				
315				imageHeight = maxHeight;
316				imageWidth = imageHeight * ratio;
317								
318				if(imageWidth < maxWidth){
319					imageWidth = maxWidth;
320					imageHeight = imageWidth / ratio;
321					
322					//center y position
323					imageLeft = 0;
324					imageTop = Math.round((imageHeight - maxHeight) / 2 * -1);
325				}else{	//center x position
326					imageTop = 0;
327					imageLeft = Math.round((imageWidth - maxWidth) / 2 * -1);
328				}
329								
330			}
331			else{		//fit to borders
332				var ratio = originalWidth / originalHeight;
333				imageHeight = maxHeight;
334				imageWidth = imageHeight * ratio;
335				imageTop = 0;
336				imageLeft = (maxWidth - imageWidth) / 2;
337				
338				if(scaleMode != "fitvert" && imageWidth > maxWidth){
339					imageWidth = maxWidth;
340					imageHeight = imageWidth / ratio;
341					imageLeft = 0;
342					imageTop = (maxHeight - imageHeight) / 2;
343				}
344			
345			}
346			
347			imageWidth = Math.floor(imageWidth);
348			imageHeight = Math.floor(imageHeight);
349			
350			imageTop = Math.floor(imageTop);
351			imageLeft = Math.floor(imageLeft);
352			
353			style="position:absolute;";
354		}
355		
356		//set padding
357		if(objPadding.padding_top)
358			imageTop += objPadding.padding_top;
359		
360		if(objPadding.padding_left)
361			imageLeft += objPadding.padding_left;
362		
363		objOutput.imageWidth = imageWidth;
364		objOutput.imageHeight = imageHeight;
365		objOutput.imageTop = imageTop;
366		objOutput.imageLeft = imageLeft;
367		objOutput.imageRight = imageLeft + imageWidth;
368		if(imageTop == 0 || imageHeight == "100%")
369			objOutput.imageBottom = null;
370		else
371			objOutput.imageBottom = imageTop + imageHeight;
372		
373		objOutput.style = style;
374		
375		return(objOutput);		
376	}
377	
378	
379	/**
380	 * get element center position inside parent 
381	 * even if the object bigger than the parent
382	 */
383	this.getElementCenterPosition = function(element, objPadding){
384		
385		var parent = element.parent();
386		var objSize = t.getElementSize(element);
387		var objSizeParent = t.getElementSize(parent);
388		
389		var parentWidth = objSizeParent.width;
390		var parentHeight = objSizeParent.height;
391		
392		if(objPadding && objPadding.padding_top !== undefined)
393			parentHeight -= objPadding.padding_top;
394		
395		if(objPadding && objPadding.padding_bottom !== undefined)
396			parentHeight -= objPadding.padding_bottom;
397		
398		if(objPadding && objPadding.padding_left !== undefined)
399			parentWidth -= objPadding.padding_left;
400		
401		if(objPadding && objPadding.padding_right !== undefined)
402			parentWidth -= objPadding.padding_right;
403		
404		
405		var output = {};
406		output.left = Math.round((parentWidth - objSize.width) / 2);
407		output.top = Math.round((parentHeight - objSize.height) / 2);
408		
409		if(objPadding && objPadding.padding_top !== undefined)
410			output.top += objPadding.padding_top;
411		
412		if(objPadding && objPadding.padding_left !== undefined)
413			output.left += objPadding.padding_left;
414		
415		
416		return(output);
417	}
418	
419	
420	/**
421	 * get the center of the element 
422	 * includeParent - including left / right related to the parent
423	 */
424	this.getElementCenterPoint = function(element, includeParent){
425		
426		if(!includeParent)
427			var includeParent = false;
428		
429		var objSize = t.getElementSize(element);
430		var output = {};
431		
432		output.x =  objSize.width / 2;
433		output.y =  objSize.height / 2;
434		
435		if(includeParent == true){
436			output.x += objSize.left;
437			output.y += objSize.top;
438		}
439		
440		output.x = Math.round(output.x);
441		output.y = Math.round(output.y);
442		
443		return(output);
444	}
445	
446	
447	/**
448	 * 
449	 * get mouse position from the event
450	 * optimised to every device
451	 */
452	this.getMousePosition = function(event, element){
453		
454		var output = {
455			pageX: 	event.pageX,
456			pageY: 	event.pageY,
457			clientX: 	event.clientX,
458			clientY: 	event.clientY
459		};
460		
461		if(event.originalEvent && event.originalEvent.touches && event.originalEvent.touches.length > 0){
462			output.pageX = event.originalEvent.touches[0].pageX;
463			output.pageY = event.originalEvent.touches[0].pageY;
464			output.clientX = event.originalEvent.touches[0].clientX;
465			output.clientY = event.originalEvent.touches[0].clientY;
466		}
467		
468		/**
469		 * get element's mouse position
470		 */
471		if(element){
472			var elementPos = element.offset();
473			output.mouseX = output.pageX - elementPos.left;
474			output.mouseY = output.pageY - elementPos.top;
475		}
476		
477		return(output);
478	}
479	
480	/**
481	 * get mouse element related point from page related point
482	 */
483	this.getMouseElementPoint = function(point, element){
484		
485		//rename the input and output
486		var newPoint = {x: point.pageX, y: point.pageY};
487		
488		var elementPoint = t.getElementLocalPoint(newPoint, element);
489		
490		return(elementPoint);
491	}
492	
493	
494	/**
495	 * get element local point from global point position
496	 */
497	this.getElementLocalPoint = function(point, element){
498		
499		var elementPoint = {};
500		var elementPos = element.offset();
501		
502		elementPoint.x = Math.round(point.x - elementPos.left);
503		elementPoint.y = Math.round(point.y - elementPos.top);
504		
505		return(elementPoint);
506	}
507
508	
509	/**
510	 * get image oritinal size
511	 * if originalWidth, originalHeight is set, just return them.
512	 */		
513	this.getImageOriginalSize = function(objImage, originalWidth, originalHeight){
514		
515		if(typeof originalWidth != "undefined" && typeof originalHeight != "undefined")
516			return({width:originalWidth, height:originalHeight});
517		
518		var htmlImage = objImage[0];
519		
520		if(typeof htmlImage == "undefined")
521			throw new Error("getImageOriginalSize error - Image not found");
522		
523		var output = {};
524		
525		if(typeof htmlImage.naturalWidth == "undefined"){
526
527			//check from cache
528			if(typeof objImage.data("naturalWidth") == "number"){
529				var output = {};
530				output.width = objImage.data("naturalWidth");
531				output.height = objImage.data("naturalHeight");
532				return(output);
533			}
534			
535		   //load new image
536		   var newImg = new Image();
537	       newImg.src = htmlImage.src;
538	        
539	       if (newImg.complete) {
540	        	output.width = newImg.width;
541	        	output.height = newImg.height;
542
543	        	//caching
544				objImage.data("naturalWidth", output.width);
545				objImage.data("naturalHeight", output.height);
546	        	return(output);
547	        	
548	       }
549	    
550	       return({width:0,height:0});
551		        
552		}else{
553			
554			output.width = htmlImage.naturalWidth;
555			output.height = htmlImage.naturalHeight;
556			
557			return(output);
558		}
559		
560	}
561
562	
563	/**
564	 * get current image ratio from original size
565	 */
566	this.getimageRatio = function(objImage){
567		
568		var originalSize = t.getImageOriginalSize(objImage);
569		var size = t.getElementSize(objImage);
570		var ratio = size.width / originalSize.width;
571		
572		return(ratio);
573	}
574	
575	/**
576	 * tells if the image fit the parent (smaller then the parent)
577	 */
578	this.isImageFitParent = function(objImage){
579		var objParent = objImage.parent();
580		var sizeImage = t.getElementSize(objImage);
581		var sizeParent = t.getElementSize(objParent);
582		
583		if(sizeImage.width <= sizeParent.width && sizeImage.height <= sizeParent.height)
584			return(true);
585		
586		return(false);
587	}
588	
589	/**
590	 * get size and position of some object
591	 */
592	this.getElementSize = function(element){
593
594		if(element === undefined){
595			throw new Error("Can't get size, empty element");
596		}
597				
598		var obj = element.position();
599				
600		obj.height = element.outerHeight();
601		obj.width = element.outerWidth();
602		
603		obj.left = Math.round(obj.left);
604		obj.top = Math.round(obj.top);
605		
606		obj.right = obj.left + obj.width;
607		obj.bottom = obj.top + obj.height;
608		
609		return(obj);		
610	}
611	
612	
613	
614	/**
615	 * return true if the element is bigger then it's parent
616	 */
617	this.isElementBiggerThenParent = function(element){
618		
619		var objParent = element.parent();
620		var objSizeElement = t.getElementSize(element);
621		var objSizeParent = t.getElementSize(objParent);
622		
623		if(objSizeElement.width > objSizeParent.width || objSizeElement.height > objSizeParent.height)
624			return(true);
625		
626		return(false);
627	}
628	
629	
630	/**
631	 * tells if the mouse point inside image
632	 * the mouse point is related to image pos
633	 */
634	this.isPointInsideElement = function(point, objSize){
635		
636		var isMouseXInside = (point.x >= 0 && point.x < objSize.width);
637		if(isMouseXInside == false)
638			return(false);
639		
640		var isMouseYInside = (point.y >= 0 && point.y < objSize.height);
641		if(isMouseYInside == false)
642			return(false);
643		
644		return(true);
645	}
646	
647	
648	/**
649	 * get element relative position according the parent
650	 * if the left / top is offset text (left , center, right / top, middle , bottom)
651	 * the element can be number size as well
652	 */
653	this.getElementRelativePos = function(element, pos, offset, objParent){
654		
655		if(!objParent)
656			var objParent = element.parent();
657		
658		if(typeof element == "number"){
659			var elementSize = {
660					width: element,
661					height: element
662			};
663		}else
664			var elementSize = t.getElementSize(element);
665		
666		var parentSize = t.getElementSize(objParent);
667		
668		
669		switch(pos){
670			case "top":
671			case "left":
672				pos = 0;
673				if(offset)
674					pos += offset;
675			break;
676			case "center":
677				pos = Math.round((parentSize.width - elementSize.width) / 2);
678				if(offset)
679					pos += offset;
680				
681			break;
682			case "right":
683				pos = parentSize.width - elementSize.width;
684				if(offset)
685					pos -= offset;
686			break;
687			case "middle":
688				pos = Math.round((parentSize.height - elementSize.height) / 2);
689				if(offset)
690					pos += offset;
691			break;
692			case "bottom":
693				pos = parentSize.height - elementSize.height;
694				if(offset)
695					pos -= offset;
696			break;
697		}
698		
699		return(pos);
700	}
701	
702		
703	
704	this.z_________SET_ELEMENT_PROPS_______ = function(){}
705		
706	
707	/**
708	 * 
709	 * zoom image inside parent
710	 * the mouse point is page offset position, can be null
711	 * return true if zoomed and false if not zoomed
712	 */
713	this.zoomImageInsideParent = function(objImage, zoomIn, step, point, scaleMode, maxZoomRatio, objPadding){
714		
715		if(!step)
716			var step = 1.2;
717		
718		if(!scaleMode)
719			var scaleMode = "fit";
720		
721		var zoomRatio = step;
722		
723		var objParent = objImage.parent();		
724		
725		var objSize = t.getElementSize(objImage);
726		var objOriginalSize = t.getImageOriginalSize(objImage);
727		
728		
729		var isMouseInside = false;
730		var newHeight,newWidth, panX = 0, panY = 0, newX, newY,panOrientX = 0, panOrientY = 0;
731		
732		if(!point){
733			isMouseInside = false;
734		}else{
735			var pointImg = t.getMouseElementPoint(point, objImage);				
736			isMouseInside = t.isPointInsideElement(pointImg, objSize);
737			
738			//if mouse point outside image, set orient to image center
739			panOrientX = pointImg.x;
740			panOrientY = pointImg.y;
741		}
742				
743		if(isMouseInside == false){
744			var imgCenterPoint = t.getElementCenterPoint(objImage);
745			panOrientX = imgCenterPoint.x;
746			panOrientY = imgCenterPoint.y;
747		}
748						
749		//zoom:
750		if(zoomIn == true){		//zoom in
751			
752			newHeight = objSize.height * zoomRatio;
753			newWidth =  objSize.width * zoomRatio;
754			
755			if(panOrientX != 0)
756				panX = -(panOrientX * zoomRatio - panOrientX);
757			
758			if(panOrientY != 0)
759				panY = -(panOrientY * zoomRatio - panOrientY);
760			
761			
762		}else{		//zoom out
763			
764			newHeight = objSize.height / zoomRatio;
765			newWidth =  objSize.width / zoomRatio;
766			
767			var objScaleData = t.getImageInsideParentData(objParent, objOriginalSize.width, objOriginalSize.height, scaleMode, objPadding);
768			
769			//go back to original size
770			if(newWidth < objScaleData.imageWidth){
771				
772				t.scaleImageFitParent(objImage, objOriginalSize.width, objOriginalSize.height, scaleMode, objPadding);
773				return(true);
774			}
775			
776			if(isMouseInside == true){
777				if(panOrientX != 0)
778					panX = -(panOrientX / zoomRatio - panOrientX);
779				
780				if(panOrientY != 0)			
781					panY = -(panOrientY / zoomRatio - panOrientY);
782			}
783			
784		}
785		
786		//check max zoom ratio, ix exeeded, abort
787		if(maxZoomRatio){
788			var expectedZoomRatio = 1;
789			if(objOriginalSize.width != 0)
790				expectedZoomRatio = newWidth / objOriginalSize.width;
791			
792			if(expectedZoomRatio > maxZoomRatio)
793				return(false);
794		}
795		
796		//resize the element
797		t.setElementSize(objImage, newWidth, newHeight);
798		
799		//set position:
800		
801		//if zoom out and mouse point not inside image, 
802		//get the image to center
803		if(zoomIn == false && isMouseInside == false){
804			var posCenter = t.getElementCenterPosition(objImage);
805			newX = posCenter.left;
806			newY = posCenter.top;
807		}else{
808			
809			newX = objSize.left + panX;
810			newY = objSize.top + panY;
811		}
812		
813		t.placeElement(objImage, newX, newY);
814		
815		return(true);
816	}
817	
818
819	
820	/**
821	 * place some element to some position
822	 * if the left / top is offset text (left , center, right / top, middle , bottom)
823	 * then put it in parent by the offset.
824	 */
825	this.placeElement = function(element, left, top, offsetLeft, offsetTop, objParent){
826		
827		
828		if(jQuery.isNumeric(left) == false || jQuery.isNumeric(top) == false){
829			
830			if(!objParent)
831				var objParent = element.parent();
832			
833			var elementSize = t.getElementSize(element);
834			var parentSize = t.getElementSize(objParent);
835		}
836		
837		//select left position
838		if(jQuery.isNumeric(left) == false){
839			
840			switch(left){
841				case "left":
842					left = 0;
843					if(offsetLeft)
844						left += offsetLeft;
845				break;
846				case "center":
847					left = Math.round((parentSize.width - elementSize.width) / 2);
848					if(offsetLeft)
849						left += offsetLeft;
850				break;
851				case "right":
852					left = parentSize.width - elementSize.width;
853					if(offsetLeft)
854						left -= offsetLeft;
855				break;
856			}
857		}
858		
859		//select top position
860		if(jQuery.isNumeric(top) == false){
861			
862			switch(top){
863				case "top":
864					top = 0;
865					if(offsetTop)
866						top += offsetTop;
867				break;
868				case "middle":
869				case "center":
870					top = Math.round((parentSize.height - elementSize.height) / 2);
871					if(offsetTop)
872						top += offsetTop;
873				break;
874				case "bottom":
875					top = parentSize.height - elementSize.height;
876					if(offsetTop)
877						top -= offsetTop;
878				break;
879			}
880			
881		}
882		
883		
884		var objCss = {
885				"position":"absolute",
886				"margin":"0px"				
887		};
888		
889		if(left !== null)
890			objCss.left = left;
891		
892		if(top !== null)
893			objCss.top = top;
894				
895		element.css(objCss);		
896	}
897	
898	
899	/**
900	 * place element inside parent center.
901	 * the element should be absolute position
902	 */
903	this.placeElementInParentCenter = function(element){
904				
905		t.placeElement(element, "center", "middle");
906	}
907	
908	
909	/**
910	 * set element size and position
911	 */
912	this.setElementSizeAndPosition = function(element,left,top,width,height){
913		
914		var objCss = {
915			"width":width+"px",
916			"height":height+"px",
917			"left":left+"px",
918			"top":top+"px",
919			"position":"absolute",
920			"margin":"0px"
921		}
922		
923		element.css(objCss);
924	}
925	
926	/**
927	 * set widht and height of the element
928	 */
929	this.setElementSize = function(element, width, height){
930		
931	    var objCss = {
932			"width":width+"px"
933		}
934	    
935	    if(height !== null && typeof height != "undefined")
936	    	objCss["height"] = height+"px"
937	    
938		element.css(objCss);	
939	}
940	
941	
942	/**
943	 * clone element size and position
944	 */
945	this.cloneElementSizeAndPos = function(objSource, objTarget, isOuter, offsetX, offsetY){
946		
947		var objSize = objSource.position();
948		
949		if(objSize == undefined){
950			throw new Error("Can't get size, empty element");
951		}
952		
953		if(isOuter === true){
954			objSize.height = objSource.outerHeight();
955			objSize.width = objSource.outerWidth();
956		}else{
957			objSize.height = objSource.height();
958			objSize.width = objSource.width();
959		}
960		
961		objSize.left = Math.round(objSize.left);
962		objSize.top = Math.round(objSize.top);
963		
964		if(offsetX)
965			objSize.left += offsetX;
966		
967		if(offsetY)
968			objSize.top += offsetY;
969		
970		t.setElementSizeAndPosition(objTarget, objSize.left, objSize.top, objSize.width, objSize.height);
971	}
972
973	
974	/**
975	 * place image inside parent, scale it by the options
976	 * and scale it to fit the parent.
977	 * scaleMode: fit, down, fill
978	 */
979	this.placeImageInsideParent = function(urlImage, objParent, originalWidth, originalHeight, scaleMode, objPadding){
980		var obj = t.getImageInsideParentData(objParent, originalWidth, originalHeight, scaleMode, objPadding);
981		
982		//set html image:
983		var htmlImage = "<img";
984		
985		if(obj.imageWidth !== null){
986			htmlImage += " width = '" + obj.imageWidth + "'";
987			obj.style += "width:" + obj.imageWidth + ";";
988		}
989		
990		if(obj.imageHeight != null){
991			
992			if(obj.imageHeight == "100%"){
993				htmlImage += " height = '" + obj.imageHeight+"'";
994				obj.style += "height:" + obj.imageHeight+";";				
995			}else{
996				htmlImage += " height = '" + obj.imageHeight + "'";
997				obj.style += "height:" + obj.imageHeight + "px;";				
998			}
999			
1000		}
1001		
1002		if(obj.imageTop !== null)
1003			obj.style += "top:"+obj.imageTop+"px;";
1004		
1005		if(obj.imageLeft !== null){
1006			obj.style += "left:"+obj.imageLeft+"px;";
1007		}
1008		
1009		urlImage = t.escapeDoubleSlash(urlImage);
1010		
1011		htmlImage += " style='"+obj.style+"'";
1012		htmlImage += " src=\""+urlImage+"\"";
1013		htmlImage += ">";
1014				
1015		objParent.html(htmlImage);
1016		
1017		//return the image just created
1018		var objImage = objParent.children("img");
1019		
1020		return(objImage);
1021	}
1022	
1023	
1024	/**
1025	 * scale image to fit parent, and place it into parent
1026	 * parent can be width , height, or object
1027	 */	
1028	this.scaleImageCoverParent = function(objImage, objParent, pHeight){
1029		
1030		if(typeof objParent == "number"){
1031			var parentWidth = objParent;
1032			var parentHeight = pHeight;
1033		}else{
1034			var parentWidth = objParent.outerWidth();
1035			var parentHeight = objParent.outerHeight();
1036		}
1037		
1038		var objOriginalSize = t.getImageOriginalSize(objImage);
1039
1040		var imageWidth = objOriginalSize.width;
1041		var imageHeight = objOriginalSize.height;
1042		
1043		var ratio = imageWidth / imageHeight;
1044		
1045		var fitHeight = parentHeight;
1046		var fitWidth = fitHeight * ratio;
1047		var posy = 0, posx = 0;
1048		
1049		if(fitWidth < parentWidth){
1050			fitWidth = parentWidth;
1051			fitHeight = fitWidth / ratio;
1052			
1053			//center y position
1054			posx = 0;
1055			posy = Math.round((fitHeight - parentHeight) / 2 * -1);
1056		}else{	//center x position
1057			posy = 0;
1058			posx = Math.round((fitWidth - parentWidth) / 2 * -1);
1059		}
1060		
1061		fitWidth = Math.round(fitWidth);
1062		fitHeight = Math.round(fitHeight);
1063		
1064		objImage.css({"width":fitWidth+"px",
1065					  "height":fitHeight+"px",
1066					  "left":posx+"px",
1067					  "top":posy+"px"});		
1068	}
1069
1070
1071	
1072	
1073	/**
1074	 * resize image to fit the parent, scale it by the options
1075	 * scaleMode: fit, down, fill
1076	 */
1077	this.scaleImageFitParent = function(objImage, originalWidth, originalHeight, scaleMode, objPadding){
1078		
1079		var objParent = objImage.parent();
1080		
1081		var obj = t.getImageInsideParentData(objParent, originalWidth, originalHeight, scaleMode, objPadding);
1082		
1083		var updateCss = false;
1084		
1085		var objCss = {};
1086		
1087		if(obj.imageWidth !== null){
1088			updateCss = true
1089			objImage.removeAttr("width");
1090			objCss["width"] = obj.imageWidth+"px";
1091		}
1092		
1093		if(obj.imageHeight != null){
1094			updateCss = true
1095			objImage.removeAttr("height");
1096			objCss["height"] = obj.imageHeight+"px";
1097		}
1098		
1099		if(obj.imageTop !== null){
1100			updateCss = true;			
1101			objCss.top = obj.imageTop+"px";
1102		}
1103		
1104		if(obj.imageLeft !== null){
1105			updateCss = true;		
1106			objCss.left = obj.imageLeft+"px";
1107		}
1108			
1109		if(updateCss == true){
1110			
1111			objCss.position = "absolute";
1112			objCss.margin = "0px 0px";
1113			
1114			objImage.css(objCss);			
1115		}
1116		
1117		
1118		return(obj);
1119	}
1120	
1121	
1122	/**
1123	 * scale image by height
1124	 */
1125	this.scaleImageByHeight = function(objImage, height, originalWidth, originalHeight){
1126		
1127		var objOriginalSize = t.getImageOriginalSize(objImage, originalWidth, originalHeight);
1128		
1129		var ratio = objOriginalSize.width / objOriginalSize.height;
1130		var width = Math.round(height * ratio);
1131		height = Math.round(height);
1132		
1133		t.setElementSize(objImage, width, height);
1134	}
1135
1136	
1137	/**
1138	 * scale image by height
1139	 */
1140	this.scaleImageByWidth = function(objImage, width, originalWidth, originalHeight){
1141		
1142		var objOriginalSize = t.getImageOriginalSize(objImage, originalWidth, originalHeight);
1143		
1144		var ratio = objOriginalSize.width / objOriginalSize.height;
1145		
1146		var height = Math.round(width / ratio);
1147		width = Math.round(width);
1148		
1149		t.setElementSize(objImage, width, height);
1150		
1151	}
1152	
1153	
1154	/**
1155	 * scale image to exact size in parent, by setting image size and padding
1156	 */
1157	this.scaleImageExactSizeInParent = function(objImage, originalWidth, originalHeight, exactWidth, exactHeight, scaleMode){
1158		
1159		var objParent = objImage.parent();
1160		var parentSize = t.getElementSize(objParent);
1161		
1162		if(parentSize.width < exactWidth)
1163			exactWidth = parentSize.width;
1164		
1165		if(parentSize.height < exactHeight)
1166			exactHeight = parentSize.height;
1167		
1168		var obj = t.getImageInsideParentData(null, originalWidth, originalHeight, scaleMode, null, exactWidth, exactHeight);
1169		
1170		var imageWidth = exactWidth;
1171		var imageHeight = exactHeight;
1172		
1173		var paddingLeft = obj.imageLeft;
1174		var paddingRight = obj.imageLeft;
1175		var paddingTop = obj.imageTop;
1176		var paddingBottom = obj.imageTop;
1177		var imageLeft = Math.round((parentSize.width - exactWidth) / 2);
1178		var imageTop = Math.round((parentSize.height - exactHeight) / 2);
1179		
1180		var totalWidth = obj.imageWidth + paddingLeft + paddingRight;
1181		var diff = exactWidth - totalWidth;
1182		if(diff != 0)
1183			paddingRight += diff;
1184		
1185		var totalHeight = obj.imageHeight + paddingTop + paddingBottom;
1186		
1187		var diff = exactHeight - totalHeight;
1188		if(diff != 0)
1189			paddingBottom += diff;
1190		
1191		//update css:
1192		objImage.removeAttr("width");
1193		objImage.removeAttr("height");
1194
1195		var objCss = {
1196				position: "absolute",
1197				margin: "0px 0px"
1198		};
1199		
1200		objCss["width"] = imageWidth+"px";
1201		objCss["height"] = imageHeight+"px";
1202		objCss["left"] = imageLeft+"px";
1203		objCss["top"] = imageTop+"px";
1204		objCss["padding-left"] = paddingLeft+"px";
1205		objCss["padding-top"] = paddingTop+"px";
1206		objCss["padding-right"] = paddingRight+"px";
1207		objCss["padding-bottom"] = paddingBottom+"px";
1208				
1209		objImage.css(objCss);
1210		
1211		//return size object
1212		
1213		var objReturn = {};
1214		objReturn["imageWidth"] = imageWidth;
1215		objReturn["imageHeight"] = imageHeight;
1216		return(objReturn);
1217	}
1218	
1219	
1220	/**
1221	 * show some element and make opacity:1
1222	 */
1223	this.showElement = function(element, element2, element3){
1224		
1225		element.show().fadeTo(0,1);
1226		
1227		if(element2)
1228			element2.show().fadeTo(0,1);
1229			
1230		if(element3)
1231				element3.show().fadeTo(0,1);
1232			
1233	}
1234	
1235		
1236	this.z_________GALLERY_RELATED_FUNCTIONS_______ = function(){}
1237	
1238	/**
1239	 * disable button
1240	 */
1241	this.disableButton = function(objButton, className){
1242		if(!className)
1243			var className = "ug-button-disabled";
1244		
1245		if(t.isButtonDisabled(objButton, className) == false)		
1246			objButton.addClass(className);		
1247	}
1248
1249	
1250	/**
1251	 * convert custom prefix options
1252	 * prefix - the prefix.
1253	 * base - after the prefix text. example lightbox_slider_option (lightbox - prefix, slider - base)
1254	 */
1255	this.convertCustomPrefixOptions = function(objOptions, prefix, base){
1256			
1257		if(!prefix)
1258			return(objOptions);
1259		
1260		var modifiedOptions = {};
1261		
1262		jQuery.each(objOptions, function(key, option){
1263			
1264			if(key.indexOf(prefix + "_"+base+"_") === 0){
1265				var newKey = key.replace(prefix+"_"+base+"_", base+"_");
1266				modifiedOptions[newKey] = option;
1267			}else{
1268				modifiedOptions[key] = option;
1269			}
1270			
1271		});
1272		
1273		return(modifiedOptions);
1274	}
1275	
1276	
1277	/**
1278	 * enable button
1279	 */
1280	this.enableButton = function(objButton, className){
1281		if(!className)
1282			var className = "ug-button-disabled";
1283		
1284		if(t.isButtonDisabled(objButton, className) == true)		
1285			objButton.removeClass(className);
1286	}
1287	
1288	
1289	/**
1290	 * check if some buggon disabled
1291	 */
1292	this.isButtonDisabled = function(objButton, className){
1293		if(!className)
1294			var className = "ug-button-disabled";
1295		
1296		if(objButton.hasClass(className))
1297			return(true);
1298		
1299		return(false);
1300	}
1301	
1302	
1303
1304	this.z_________MATH_FUNCTIONS_______ = function(){}
1305	
1306	/**
1307	 * 
1308	 * normalize the value for readable "human" setting value.
1309	 */
1310	this.normalizeSetting = function(realMin, realMax, settingMin, settingMax, value, fixBounds){
1311		if(!fixBounds)
1312			var fixBounds = false;
1313		
1314		var ratio = (value - settingMin)  / (settingMax - settingMin);
1315		value = realMin + (realMax - realMin) * ratio;
1316		
1317		if(fixBounds == true){
1318			if(value < realMin)
1319				value = realMin;
1320			
1321			if(value > realMax)
1322				value = realMax;
1323		}
1324		
1325		return(value);
1326	}
1327
1328	
1329	/**
1330	 * 
1331	 * get "real" setting from normalized setting
1332	 */
1333	this.getNormalizedValue = function(realMin, realMax, settingMin, settingMax, realValue){
1334		
1335		var ratio = (realValue - realMin)  / (realMax - realMin);
1336		realValue = realMin + (settingMax - settingMin) * ratio;
1337		
1338		return(realValue);
1339	}
1340	
1341	
1342	/**
1343	 * get distance between 2 points
1344	 */
1345	this.getDistance = function(x1,y1,x2,y2) {
1346		
1347		var distance = Math.round(Math.sqrt(Math.abs(((x2-x1)*(x2-x1)) + ((y2-y1)*(y2-y1)))));
1348		
1349		return distance;
1350	}
1351	
1352	
1353	/**
1354	 * get center point of the 2 points
1355	 */
1356	this.getMiddlePoint = function(x1,y1,x2,y2){
1357		var output = {}
1358		output.x = x1 + Math.round((x2 - x1) / 2);
1359		output.y = y1 + Math.round((y2 - y1) / 2);
1360		
1361		return(output);
1362	}
1363	
1364	
1365	/**
1366	 * get number of items in space width gap
1367	 * even item sizes
1368	 * by lowest
1369	 */
1370	this.getNumItemsInSpace = function(spaceSize, itemsSize, gapSize){
1371		var numItems = Math.floor((spaceSize + gapSize) / (itemsSize + gapSize));
1372		return(numItems);
1373	}
1374
1375	/**
1376	 * get number of items in space width gap
1377	 * even item sizes
1378	 * by Math.round
1379	 */
1380	this.getNumItemsInSpaceRound = function(spaceSize, itemsSize, gapSize){
1381		var numItems = Math.round((spaceSize + gapSize) / (itemsSize + gapSize));
1382		return(numItems);
1383	}
1384
1385	/**
1386	 * get space (width in carousel for example) by num items, item size, and gap size
1387	 */
1388	this.getSpaceByNumItems = function(numItems, itemSize, gapSize){
1389		var space = numItems * itemSize + (numItems-1) * gapSize;
1390		return(space);
1391	}
1392	
1393
1394	/**
1395	 * get item size by space and gap
1396	 */
1397	this.getItemSizeInSpace = function(spaceSize, numItems, gapSize){
1398		var itemSize = Math.floor((spaceSize - (numItems-1) * gapSize) / numItems);
1399		
1400		return(itemSize);
1401	}
1402	
1403	
1404	/**
1405	 * get column x pos with even column sizes, start from 0
1406	 */
1407	this.getColX = function(col, colWidth, colGap){
1408		
1409		var posx = col * (colWidth + colGap);
1410		
1411		return posx;
1412	}
1413	
1414
1415	/**
1416	 * get column number by index
1417	 */
1418	this.getColByIndex = function(numCols, index){
1419		var col = index % numCols;
1420		return(col);
1421	}
1422	
1423	
1424	/**
1425	 * get col and row by index
1426	 */
1427	this.getColRowByIndex = function(index, numCols){
1428		
1429		var row = Math.floor(index / numCols);
1430		var col = Math.floor(index % numCols);
1431		
1432		return({col:col,row:row});
1433	}
1434	
1435	
1436	/**
1437	 * get index by row, col, numcols
1438	 */
1439	this.getIndexByRowCol = function(row, col, numCols){
1440		
1441		if(row < 0)
1442			return(-1);
1443		
1444		if(col < 0)
1445			return(-1);
1446		
1447		var index = row * numCols + col;
1448		return(index);
1449	}
1450	
1451	/**
1452	 * get previous row item in the same column
1453	 */
1454	this.getPrevRowSameColIndex = function(index, numCols){
1455		var obj = t.getColRowByIndex(index, numCols);
1456		var prevIndex = t.getIndexByRowCol(obj.row-1, obj.col, numCols);
1457		return(prevIndex);
1458	}
1459	
1460	/**
1461	 * get next row item in the same column
1462	 */
1463	this.getNextRowSameColIndex = function(index, numCols){
1464		var obj = t.getColRowByIndex(index, numCols);
1465		var nextIndex = t.getIndexByRowCol(obj.row+1, obj.col, numCols);
1466		return(nextIndex);
1467	}
1468	
1469	
1470	this.z_________DATA_FUNCTIONS_______ = function(){}
1471	
1472	/**
1473	 * set data value
1474	 */
1475	this.setGlobalData = function(key, value){
1476		
1477		jQuery.data(document.body, key, value);
1478		
1479	}
1480	
1481	/**
1482	 * get global data
1483	 */
1484	this.getGlobalData = function(key){
1485		
1486		var value = jQuery.data(document.body, key);
1487		
1488		return(value);
1489	}
1490	
1491	this.z_________EVENT_DATA_FUNCTIONS_______ = function(){}
1492
1493	
1494	/**
1495	 * handle scroll top, return if scroll mode or not
1496	 */
1497	this.handleScrollTop = function(storedEventID){
1498		
1499		if(t.isTouchDevice() == false)
1500			return(null);
1501		
1502		var objData = t.getStoredEventData(storedEventID);
1503		
1504		var horPass = 15;
1505		var vertPass = 15;
1506		
1507		//check if need to set some movement
1508		if(objData.scrollDir === null){
1509			
1510			if(Math.abs(objData.diffMouseX) > horPass)
1511				objData.scrollDir = "hor";
1512			else
1513				if(Math.abs(objData.diffMouseY) > vertPass && Math.abs(objData.diffMouseY) > Math.abs(objData.diffMouseX) ){
1514					objData.scrollDir = "vert";
1515					objData.scrollStartY = objData.lastMouseClientY;
1516					objData.scrollOrigin = jQuery(document).scrollTop();
1517					
1518					g_temp.dataCache[storedEventID].scrollStartY = objData.lastMouseClientY;
1519					g_temp.dataCache[storedEventID].scrollOrigin = objData.scrollOrigin;
1520				}
1521			
1522			//update scrollDir
1523			g_temp.dataCache[storedEventID].scrollDir = objData.scrollDir;
1524		}
1525				
1526		if(objData.scrollDir !== "vert")
1527			return(objData.scrollDir);
1528		
1529		
1530		var currentScroll = jQuery(document).scrollTop();
1531		
1532		var scrollPos = objData.scrollOrigin - (objData.lastMouseClientY - objData.scrollStartY);
1533		
1534		if(scrollPos >= 0)
1535			jQuery(document).scrollTop(scrollPos);
1536		
1537		return(objData.scrollDir);
1538	}
1539
1540	
1541	/**
1542	 * return true / false if was vertical scrolling
1543	 */
1544	this.wasVerticalScroll = function(storedEventID){
1545		var objData = t.getStoredEventData(storedEventID);
1546		
1547		if(objData.scrollDir === "vert")
1548			return(true);
1549		
1550		return(false);
1551	}
1552	
1553	
1554	/**
1555	 * store event data
1556	 */
1557	this.storeEventData = function(event, id, addData){
1558				
1559		var mousePos = t.getMousePosition(event);
1560		var time = jQuery.now();
1561		
1562		var obj = {
1563				startTime: time,
1564				lastTime: time,
1565				startMouseX: mousePos.pageX,
1566				startMouseY: mousePos.pageY,
1567				lastMouseX: mousePos.pageX,
1568				lastMouseY: mousePos.pageY,
1569				
1570				startMouseClientY: mousePos.clientY,
1571				lastMouseClientY: mousePos.clientY,
1572				
1573				scrollTop: jQuery(document).scrollTop(),
1574				scrollDir: null
1575		};
1576		
1577		if(addData)
1578			obj = jQuery.extend(obj, addData);
1579		
1580		g_temp.dataCache[id] = obj;
1581		
1582	}
1583	
1584	
1585	/**
1586	 * update event data with last position
1587	 */
1588	this.updateStoredEventData = function(event, id, addData){
1589		
1590		if(!g_temp.dataCache[id])
1591			throw new Error("updateEventData error: must have stored cache object");
1592		
1593		var obj = g_temp.dataCache[id];
1594		
1595		var mousePos = t.getMousePosition(event);
1596		obj.lastTime = jQuery.now();
1597		
1598		if(mousePos.pageX !== undefined){
1599			obj.lastMouseX = mousePos.pageX;
1600			obj.lastMouseY = mousePos.pageY;
1601			obj.lastMouseClientY = mousePos.clientY;
1602		}
1603		
1604		if(addData)
1605			obj = jQuery.extend(obj, addData);
1606		
1607		g_temp.dataCache[id] = obj;
1608	}
1609	
1610	/**
1611	 * get stored event data
1612	 */
1613	this.getStoredEventData = function(id, isVertical){
1614		if(!g_temp.dataCache[id])
1615			throw new Error("updateEventData error: must have stored cache object");
1616		
1617		var obj = g_temp.dataCache[id];
1618		
1619		obj.diffMouseX = obj.lastMouseX - obj.startMouseX;
1620		obj.diffMouseY = obj.lastMouseY - obj.startMouseY;
1621		
1622		obj.diffMouseClientY = obj.lastMouseClientY - obj.startMouseClientY;
1623		
1624		obj.diffTime = obj.lastTime - obj.startTime;
1625		
1626		//get mouse position according orientation
1627		if(isVertical === true){
1628			obj.startMousePos = obj.lastMouseY;
1629			obj.lastMousePos = obj.lastMouseY;
1630			obj.diffMousePos = obj.diffMouseY;
1631		}else{
1632			obj.startMousePos = obj.lastMouseX;
1633			obj.lastMousePos = obj.lastMouseX;
1634			obj.diffMousePos = obj.diffMouseX;			
1635		}
1636		
1637		return(obj);
1638	}
1639	
1640	/**
1641	 * return if click event approved according the done motion
1642	 */
1643	this.isApproveStoredEventClick = function(id, isVertical){
1644		
1645		if(!g_temp.dataCache[id])
1646			return(true);
1647		
1648		var objData = t.getStoredEventData(id, isVertical);
1649		
1650		var passedDistanceAbs = Math.abs(objData.diffMousePos);
1651		
1652		if(objData.diffTime > 400)
1653			return(false);
1654		
1655		if(passedDistanceAbs > 30)
1656			return(false);
1657		
1658		return(true);
1659		
1660	}
1661	
1662	
1663	/**
1664	 * clear stored event data
1665	 */
1666	this.clearStoredEventData = function(id){
1667		g_temp.dataCache[id] = null;
1668	}
1669
1670	this.z_________CHECK_SUPPORT_FUNCTIONS_______ = function(){}
1671	
1672	
1673	
1674	/**
1675	 * is canvas exists in the browser
1676	 */
1677	this.isCanvasExists = function(){
1678		
1679		var canvas = jQuery('<canvas width="500" height="500" > </canvas>')[0];
1680		
1681		if(typeof canvas.getContext == "function")
1682			return(true);
1683		
1684		return(false);
1685	}
1686	
1687	/**
1688	 * tells if vertical scrollbar exists
1689	 */
1690	this.isScrollbarExists = function(){
1691		var hasScrollbar = window.innerWidth > document.documentElement.clientWidth;
1692		return(hasScrollbar);
1693	}
1694	
1695	/**
1696	 * check if this device are touch enabled
1697	 */
1698	this.isTouchDevice = function(){
1699		
1700		  //get from cache
1701		  if(g_temp.isTouchDevice !== -1)
1702			  return(g_temp.isTouchDevice);
1703		  
1704		  try{ 
1705			  document.createEvent("TouchEvent"); 
1706			  g_temp.isTouchDevice = true; 
1707		  }
1708		  catch(e){ 
1709			  g_temp.isTouchDevice = false; 
1710		  }
1711		  
1712		  return(g_temp.isTouchDevice);
1713	}
1714	
1715	
1716	
1717	/**
1718	 * check if 
1719	 */
1720	this.isRgbaSupported = function(){
1721		
1722		if(g_temp.isRgbaSupported !== -1)
1723			return(g_temp.isRgbaSupported);
1724		
1725		var scriptElement = document.getElementsByTagName('script')[0];
1726		var prevColor = scriptElement.style.color;
1727		try {
1728			scriptElement.style.color = 'rgba(1,5,13,0.44)';
1729		} catch(e) {}
1730		var result = scriptElement.style.color != prevColor;
1731		scriptElement.style.color = prevColor;
1732		
1733		g_temp.isRgbaSupported = result;
1734		
1735		return result;
1736	}
1737	
1738	this.z_________GENERAL_FUNCTIONS_______ = function(){}
1739	
1740	
1741	/**
1742	 * check if current jquery version is more then minimal version
1743	 * version can be "1.8.0" for example
1744	 */
1745	this.checkMinJqueryVersion = function(version){
1746
1747	   var arrCurrent = jQuery.fn.jquery.split('.');
1748       var arrMin = version.split('.');
1749	  
1750	  for (var i=0, len=arrCurrent.length; i<len; i++) {
1751		  
1752		  var numCurrent = parseInt(arrCurrent[i]);
1753	      var numMin = parseInt(arrMin[i]);
1754
1755	      if(typeof arrMin[i] == "undefined")
1756	    	  return(true);
1757	      
1758	      if(numMin > numCurrent)
1759	    	  return(false);
1760	      
1761	      if(numCurrent > numMin)
1762	    	  return(true);
1763	  }
1764	  
1765	  
1766	  //if all equal then all ok
1767	  return true;
1768	}
1769
1770	
1771	/**
1772	 * get css size parameter, like width. if % given, leave it, if number without px - add px.
1773	 */
1774	this.getCssSizeParam = function(sizeParam){
1775		if(jQuery.isNumeric(sizeParam))
1776			return(sizeParam + "px");
1777			
1778		return(sizeParam);
1779	}
1780	
1781	/**
1782	 * convert hex color to rgb color
1783	 */
1784	this.convertHexToRGB = function(hexInput, opacity){
1785	    
1786		var hex = hexInput.replace('#','');
1787	    if(hex === hexInput)
1788	    	return(hexInput);
1789	    
1790	    r = parseInt(hex.substring(0,2), 16);
1791	    g = parseInt(hex.substring(2,4), 16);
1792	    b = parseInt(hex.substring(4,6), 16);
1793	    result = 'rgba('+r+','+g+','+b+','+opacity+')';
1794	    return result;
1795	}	
1796	
1797	/**
1798	 * get timestamp to string
1799	 */
1800	this.timestampToString = function(stamp){
1801		
1802		var d = new Date(stamp);
1803		var str = d.getDate() + "/" + d.getMonth();
1804		str += " " + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + ":" + d.getMilliseconds();
1805		
1806		return(str);
1807	}
1808	
1809	/**
1810	 * get touches array (if exists) from the event
1811	 */
1812	this.getArrTouches = function(event){
1813		
1814		var arrTouches = [];
1815				
1816		if(event.originalEvent && event.originalEvent.touches && event.originalEvent.touches.length > 0){			
1817			arrTouches = event.originalEvent.touches;
1818		}
1819		
1820		return(arrTouches);
1821	}
1822	
1823	/**
1824	 * extract touch positions from arrTouches
1825	 */
1826	this.getArrTouchPositions = function(arrTouches){
1827		
1828		var arrOutput = [];
1829		
1830		for(var i=0;i<arrTouches.length;i++){
1831			
1832			var point = {
1833				pageX:arrTouches[i].pageX,
1834				pageY:arrTouches[i].pageY
1835			};
1836			
1837			arrOutput.push(point);
1838		}
1839		
1840		return(arrOutput);
1841	}
1842	
1843	
1844	/**
1845	 * start time debug
1846	 */
1847	this.startTimeDebug = function(){
1848		g_temp.starTime = jQuery.now();
1849	}
1850	
1851	/**
1852	 * show time debug
1853	 */
1854	this.showTimeDebug = function(){
1855		
1856		var endTime = jQuery.now();
1857		var diffTime = endTime - g_temp.starTime;
1858		
1859		debugLine({"Time Passed": diffTime},true);
1860	}
1861	
1862		
1863	/**
1864	 * put progress indicator to some parent by type
1865	 * return the progress indicator object
1866	 */
1867	this.initProgressIndicator = function(type, options, objParent){
1868		
1869		//check canvas compatability
1870		if(type != "bar" && t.isCanvasExists() == false)
1871			type = "bar";
1872		
1873		//put the progress indicator
1874		switch(type){
1875			case "bar":
1876				var g_objProgress = new UGProgressBar();		
1877				g_objProgress.putHidden(objParent, options);
1878			break;
1879			default:
1880			case "pie":
1881				var g_objProgress = new UGProgressPie();		
1882				g_objProgress.putHidden(objParent, options);
1883			break;			
1884			case "pie2":
1885				options.type_fill = true;
1886				
1887				var g_objProgress = new UGProgressPie();				
1888				g_objProgress.putHidden(objParent, options);
1889			break;			
1890		}
1891		
1892		return(g_objProgress);
1893	}
1894	
1895	
1896	/**
1897	 * add to button ug-nohover class on ipad
1898	 * need to be processed in css
1899	 */
1900	this.setButtonMobileReady = function(objButton){
1901		
1902		objButton.on("touchstart",function(event){
1903			//event.preventDefault();
1904			jQuery(this).addClass("ug-nohover");
1905		});
1906		
1907		objButton.on("mousedown touchend",function(event){
1908			
1909			//debugLine("button touchend",true,true);
1910			//event.preventDefault();
1911			event.stopPropagation();
1912			event.stopImmediatePropagation();
1913			
1914			//debugLine(event.type, true, true);
1915			
1916			return(false);
1917		});
1918		
1919	}
1920	
1921	
1922	/**
1923	 * register gallery theme
1924	 */
1925	this.registerTheme = function(themeName){
1926		
1927		g_temp.arrThemes.push(themeName);
1928	}
1929	
1930	/**
1931	 * get themes array
1932	 */
1933	this.getArrThemes = function(){
1934		
1935		return(g_temp.arrThemes);
1936	}
1937	
1938	
1939	/**
1940	 * check if theme exists
1941	 */
1942	this.isThemeRegistered = function(theme){
1943	
1944		if(jQuery.inArray(theme, g_temp.arrThemes) !== -1)
1945			return(true);
1946		
1947		return(false);
1948	}
1949	
1950	/**
1951	 * get first registered theme name
1952	 */
1953	this.getFirstRegisteredTheme = function(){
1954		if(g_temp.arrThemes.length == 0)
1955			return("");
1956		var themeName = g_temp.arrThemes[0];
1957		
1958		return(themeName);
1959	}
1960
1961	
1962	
1963	
1964	/**
1965	 * function checks if enought time passsed between function calls.
1966	 * good for filtering same time events
1967	 */
1968	this.isTimePassed = function(handlerName, timeLimit){
1969		
1970		if(!timeLimit)
1971			var timeLimit = 100;
1972		
1973		var currentTime = jQuery.now();
1974		if(g_temp.timeCache.hasOwnProperty(handlerName) == false)
1975			lastTime = 0;
1976		else
1977			lastTime = g_temp.timeCache[handlerName];
1978		
1979		var diffTime = currentTime - lastTime;
1980		
1981		g_temp.timeCache[handlerName] = currentTime;
1982		
1983		//debugLine(diffTime,true,true);
1984		
1985		if(diffTime <= timeLimit)
1986			return(false);
1987				
1988		return(true);
1989	}
1990	
1991	
1992	/**
1993	 * check if continious event is over like resize
1994	 */
1995	this.whenContiniousEventOver = function(handlerName, onEventOver, timeLimit){
1996		
1997		if(!timeLimit)
1998			var timeLimit = 300;
1999		
2000		
2001		if(g_temp.timeCache.hasOwnProperty(handlerName) == true && g_temp.timeCache[handlerName] != null){
2002			clearTimeout(g_temp.timeCache[handlerName]);
2003			g_temp.timeCache[handlerName] = null;			
2004		}
2005		
2006		g_temp.timeCache[handlerName] = setTimeout(onEventOver, timeLimit);
2007	}
2008	
2009	
2010	/**
2011	 * validate click and touchstart events. 
2012	 * if click comes after touchstart, return false.
2013	 */
2014	this.validateClickTouchstartEvent = function(eventType){
2015		
2016		var returnVal = true;
2017		
2018		var diff = jQuery.now() - g_temp.lastEventTime;
2019		
2020		//debugLine({lastType:g_temp.lastEventType, diff:diff},true, true);
2021		
2022		if(eventType == "click" && g_temp.lastEventType == "touchstart" && diff < 1000)
2023			returnVal = false;
2024		
2025		g_temp.lastEventTime = jQuery.now();
2026		g_temp.lastEventType = eventType;
2027		
2028		return(returnVal);
2029	}
2030	
2031	/**
2032	 * add some class on hover (hover event)
2033	 */
2034	this.addClassOnHover = function(element,className){
2035		if(!className)
2036			var className = "ug-button-hover";
2037		
2038		element.hover(function(){
2039			jQuery(this).addClass(className);
2040		},function(){				
2041			jQuery(this).removeClass(className);
2042		});
2043		
2044	}
2045	
2046	/**
2047	 * destroy hover effect on elements
2048	 */
2049	this.destroyButton = function(element){
2050		element.off("mouseenter");
2051		element.off("mouseleave");
2052		element.off("click");
2053		element.off("touchstart");
2054		element.off("touchend");
2055		element.off("mousedown");
2056		element.off("tap");
2057	}
2058	
2059	/**
2060	 * set button on click event, advanced
2061	 */
2062	this.setButtonOnClick = function(objButton, onClickFunction){
2063		
2064		t.setButtonMobileReady(objButton);
2065		
2066		objButton.on("click touchstart", function(event){
2067			
2068			objThis = jQuery(this);
2069						
2070			event.stopPropagation();
2071			event.stopImmediatePropagation();
2072			
2073			if(t.validateClickTouchstartEvent(event.type) == false)
2074				return(true);
2075			
2076			onClickFunction(objThis, event);
2077		});
2078		
2079	}
2080	
2081	
2082	/**
2083	 * set button on tap
2084	 */
2085	this.setButtonOnTap = function(objButton, onClickFunction){
2086		
2087		//set the event
2088		objButton.on("tap",onClickFunction);
2089		
2090		//set tap event trigger
2091		if(t.isTouchDevice() == false){
2092			
2093			objButton.on("click", function(event){
2094				var objElement = jQuery(this);
2095				
2096				if(t.validateClickTouchstartEvent(event.type) == false)
2097					return(true);
2098				
2099				objElement.trigger("tap");
2100			});
2101			
2102		}else{
2103			
2104			//set tap event
2105			objButton.on("touchstart",function(event){
2106				
2107				var objElement = jQuery(this);
2108				
2109				objElement.addClass("ug-nohover");
2110							
2111				g_temp.lastTouchStartElement = jQuery(this);
2112				g_temp.lastEventTime = jQuery.now();
2113			});
2114			
2115			objButton.on("touchend", function(event){
2116				var objElement = jQuery(this);
2117				
2118				//validate same element
2119				if(objElement.is(g_temp.lastTouchStartElement) == false)
2120					return(true);
2121				
2122				//validate time passed
2123				if(!g_temp.lastEventTime)
2124					return(true);
2125				
2126				var timePassed = jQuery.now() - g_temp.lastEventTime;
2127				if(timePassed > g_temp.touchThreshold)
2128					return(true);
2129				
2130				objElement.trigger("tap");
2131			});
2132			
2133		}
2134		
2135		
2136	}
2137	
2138	
2139	/**
2140	 * load javascript dynamically
2141	 */
2142	this.loadJs = function(url, addProtocol){
2143		
2144		if(addProtocol === true)
2145			url = location.protocol + "//" + url;
2146		
2147		var tag = document.createElement('script');
2148		tag.src = url;
2149		var firstScriptTag = document.getElementsByTagName('script')[0];
2150		firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);		
2151	}
2152	
2153	/**
2154	 * load css dymanically
2155	 */
2156	this.loadCss = function(url, addProtocol){
2157		if(addProtocol === true)
2158			url = location.protocol + "//" + url;
2159		
2160		var tag=document.createElement("link");
2161		  tag.setAttribute("rel", "stylesheet");
2162		  tag.setAttribute("type", "text/css");
2163		  tag.setAttribute("href", url);
2164		  
2165		document.getElementsByTagName("head")[0].appendChild(tag);
2166	}
2167	
2168	/**
2169	 * add event listener with old browsers fallback
2170	 */
2171	 this.addEvent = function(elem, event, func ) {
2172		 
2173		 if (typeof (elem.addEventListener) != "undefined") {
2174			 elem.addEventListener(event, func, false);
2175		    } else if (elem.attachEvent) {
2176		    	elem.attachEvent('on' + event, func);
2177		  }
2178		 
2179	  }
2180
2181
2182
2183
2184	/**
2185	 * fire event where all images are loaded
2186	 */
2187	this.checkImagesLoaded = function(objImages, onComplete, onProgress){
2188		
2189		var arrImages = [];
2190		var counter = 0;
2191		var numImages = objImages.length;
2192		
2193		//if no images - exit
2194		if(numImages == 0 && onComplete){
2195			onComplete();
2196			return(false);
2197		}
2198		
2199		//nested function
2200		function checkComplete(image, isError){
2201			counter++;
2202						
2203			if(typeof onProgress == "function"){
2204				
2205				setTimeout(function(){
2206					onProgress(image, isError);
2207				});
2208			}
2209			
2210			if(counter == numImages && typeof onComplete == "function"){
2211				setTimeout(function(){
2212					onComplete();
2213				});
2214			}
2215			
2216		}
2217
2218
2219		//start a little later
2220		setTimeout(function(){
2221			
2222			//start the function
2223			for(var index=0;
2223index < numImages; index++){
2224				var image = objImages[index];
2225				
2226				//arrImages.push(jQuery(image));
2227				if(image.naturalWidth !== undefined && image.naturalWidth !== 0){
2228					checkComplete(objImages[index], false);
2229				}
2230				else{
2231					var proxyImage = jQuery('<img/>');
2232					proxyImage.data("index", index);
2233					
2234					proxyImage.on("load", function(){
2235						var index = jQuery(this).data("index");
2236						checkComplete(objImages[index], false);
2237					});
2238					proxyImage.on("error", function(){
2239						var index = jQuery(this).data("index");
2240						checkComplete(objImages[index], true);
2241					});
2242					proxyImage.attr("src", image.src);			
2243				}
2244			}
2245			
2246		});
2247		
2248		
2249	}
2250	
2251	
2252	/**
2253	 * run the function when the element size will be not 0
2254	 */
2255	this.waitForWidth = function(element, func){
2256		var width = element.width();
2257		if(width != 0){
2258			func();
2259			return(false);
2260		}
2261
2262		g_temp.handle = setInterval(function(){
2263			width = element.width();
2264			if(width != 0){
2265				clearInterval(g_temp.handle);
2266				func();				
2267			}
2268
2269		}, 300);
2270		
2271	}
2272	
2273	/**
2274	 * shuffle (randomise) array
2275	 */
2276	this.arrayShuffle = function(arr){
2277		
2278		if(typeof arr != "object")
2279			return(arr);
2280			
2281	    for(var j, x, i = arr.length; i; j = parseInt(Math.random() * i), x = arr[--i], arr[i] = arr[j], arr[j] = x);
2282	    return arr;
2283	}
2284
2285	
2286	/**
2287	 * get object length
2288	 */
2289	this.getObjectLength = function(object){
2290		var num = 0;
2291		for(var item in object)
2292			num++;
2293		return num;
2294	}
2295
2296	/**
2297	 * normalize the percent, return always between 0 and 1
2298	 */
2299	this.normalizePercent = function(percent){
2300		
2301		if(percent < 0)
2302			percent = 0;
2303		
2304		if(percent > 1)
2305			percent = 1;
2306		
2307		return(percent);
2308	}
2309	
2310	
2311	/**
2312	 * strip tags from string
2313	 */
2314	this.stripTags = function(html){
2315		
2316		var text = html.replace(/(<([^>]+)>)/ig,"");
2317		
2318		return(text);
2319	}
2320	
2321	
2322	/**
2323	 * escape double slash
2324	 */
2325	this.escapeDoubleSlash = function(str){
2326		
2327		return str.replace('"','\"');
2328	}
2329	
2330	
2331	/**
2332	 * html entitles
2333	 */
2334	this.htmlentitles = function(html){
2335		var text = jQuery('<div/>').text(html).html();
2336		return(text);
2337	}
2338	
2339	
2340	this.z_________END_GENERAL_FUNCTIONS_______ = function(){}
2341	
2342}
2343
2344
2345
2346var g_ugFunctions = new UGFunctions();
2347
2348
2349/** -------------- END UgFunctions class ---------------------*/
2350
2351
2352
2353/** -------------- MouseWheel ---------------------*/
2354
2355!function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?module.exports=e:e(jQuery)}(function(e){function t(t){var s=t||window.event,a=h.call(arguments,1),u=0,r=0,d=0,f=0;if(t=e.event.fix(s),t.type="mousewheel","detail"in s&&(d=-1*s.detail),"wheelDelta"in s&&(d=s.wheelDelta),"wheelDeltaY"in s&&(d=s.wheelDeltaY),"wheelDeltaX"in s&&(r=-1*s.wheelDeltaX),"axis"in s&&s.axis===s.HORIZONTAL_AXIS&&(r=-1*d,d=0),u=0===d?r:d,"deltaY"in s&&(d=-1*s.deltaY,u=d),"deltaX"in s&&(r=s.deltaX,0===d&&(u=-1*r)),0!==d||0!==r){if(1===s.deltaMode){var c=e.data(this,"mousewheel-line-height");u*=c,d*=c,r*=c}else if(2===s.deltaMode){var m=e.data(this,"mousewheel-page-height");u*=m,d*=m,r*=m}return f=Math.max(Math.abs(d),Math.abs(r)),(!l||l>f)&&(l=f,i(s,f)&&(l/=40)),i(s,f)&&(u/=40,r/=40,d/=40),u=Math[u>=1?"floor":"ceil"](u/l),r=Math[r>=1?"floor":"ceil"](r/l),d=Math[d>=1?"floor":"ceil"](d/l),t.deltaX=r,t.deltaY=d,t.deltaFactor=l,t.deltaMode=0,a.unshift(t,u,r,d),o&&clearTimeout(o),o=setTimeout(n,200),(e.event.dispatch||e.event.handle).apply(this,a)}}function n(){l=null}function i(e,t){return r.settings.adjustOldDeltas&&"mousewheel"===e.type&&t%120===0}var o,l,s=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],a="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],h=Array.prototype.slice;if(e.event.fixHooks)for(var u=s.length;u;)e.event.fixHooks[s[--u]]=e.event.mouseHooks;var r=e.event.special.mousewheel={version:"3.1.9",setup:function(){if(this.addEventListener)for(var n=a.length;n;)this.addEventListener(a[--n],t,!1);else this.onmousewheel=t;e.data(this,"mousewheel-line-height",r.getLineHeight(this)),e.data(this,"mousewheel-page-height",r.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var e=a.length;e;)this.removeEventListener(a[--e],t,!1);else this.onmousewheel=null},getLineHeight:function(t){return parseInt(e(t)["offsetParent"in e.fn?"offsetParent":"parent"]().css("fontSize"),10)},getPageHeight:function(t){return e(t).height()},settings:{adjustOldDeltas:!0}};e.fn.extend({mousewheel:function(e){return e?this.bind("mousewheel",e):this.trigger("mousewheel")},unmousewheel:function(e){return this.unbind("mousewheel",e)}})});
2356
2357/** -------------- EASING FUNCTIONS ---------------------*/
2358
2359(function(factory){if(typeof define==="function"&&define.amd){define(["jquery"],function($){return factory($)})}else if(typeof module==="object"&&typeof module.exports==="object"){exports=factory(require("jquery"))}else{factory(jQuery)}})(function($){$.easing["jswing"]=$.easing["swing"];var pow=Math.pow,sqrt=Math.sqrt,sin=Math.sin,cos=Math.cos,PI=Math.PI,c1=1.70158,c2=c1*1.525,c3=c1+1,c4=2*PI/3,c5=2*PI/4.5;function bounceOut(x){var n1=7.5625,d1=2.75;if(x<1/d1){return n1*x*x}else if(x<2/d1){return n1*(x-=1.5/d1)*x+.75}else if(x<2.5/d1){return n1*(x-=2.25/d1)*x+.9375}else{return n1*(x-=2.625/d1)*x+.984375}}$.extend($.easing,{def:"easeOutQuad",swing:function(x){return $.easing[$.easing.def](x)},easeInQuad:function(x){return x*x},easeOutQuad:function(x){return 1-(1-x)*(1-x)},easeInOutQuad:function(x){return x<.5?2*x*x:1-pow(-2*x+2,2)/2},easeInCubic:function(x){return x*x*x},easeOutCubic:function(x){return 1-pow(1-x,3)},easeInOutCubic:function(x){return x<.5?4*x*x*x:1-pow(-2*x+2,3)/2},easeInQuart:function(x){return x*x*x*x},easeOutQuart:function(x){return 1-pow(1-x,4)},easeInOutQuart:function(x){return x<.5?8*x*x*x*x:1-pow(-2*x+2,4)/2},easeInQuint:function(x){return x*x*x*x*x},easeOutQuint:function(x){return 1-pow(1-x,5)},easeInOutQuint:function(x){return x<.5?16*x*x*x*x*x:1-pow(-2*x+2,5)/2},easeInSine:function(x){return 1-cos(x*PI/2)},easeOutSine:function(x){return sin(x*PI/2)},easeInOutSine:function(x){return-(cos(PI*x)-1)/2},easeInExpo:function(x){return x===0?0:pow(2,10*x-10)},easeOutExpo:function(x){return x===1?1:1-pow(2,-10*x)},easeInOutExpo:function(x){return x===0?0:x===1?1:x<.5?pow(2,20*x-10)/2:(2-pow(2,-20*x+10))/2},easeInCirc:function(x){return 1-sqrt(1-pow(x,2))},easeOutCirc:function(x){return sqrt(1-pow(x-1,2))},easeInOutCirc:function(x){return x<.5?(1-sqrt(1-pow(2*x,2)))/2:(sqrt(1-pow(-2*x+2,2))+1)/2},easeInElastic:function(x){return x===0?0:x===1?1:-pow(2,10*x-10)*sin((x*10-10.75)*c4)},easeOutElastic:function(x){return x===0?0:x===1?1:pow(2,-10*x)*sin((x*10-.75)*c4)+1},easeInOutElastic:function(x){return x===0?0:x===1?1:x<.5?-(pow(2,20*x-10)*sin((20*x-11.125)*c5))/2:pow(2,-20*x+10)*sin((20*x-11.125)*c5)/2+1},easeInBack:function(x){return c3*x*x*x-c1*x*x},easeOutBack:function(x){return 1+c3*pow(x-1,3)+c1*pow(x-1,2)},easeInOutBack:function(x){return x<.5?pow(2*x,2)*((c2+1)*2*x-c2)/2:(pow(2*x-2,2)*((c2+1)*(x*2-2)+c2)+2)/2},easeInBounce:function(x){return 1-bounceOut(1-x)},easeOutBounce:bounceOut,easeInOutBounce:function(x){return x<.5?(1-bounceOut(1-2*x))/2:(1+bounceOut(2*x-1))/2}})});
2360
2361/** -------------- JQuery Color Animations ---------------------*/
2362
2363!function(r,n){
2364	if(typeof r.cssHooks == "undefined")		//error protection
2365		return(false);
2366	function t(r,n,t){var e=f[n.type]||{};return null==r?t||!n.def?null:n.def:(r=e.floor?~~r:parseFloat(r),isNaN(r)?n.def:e.mod?(r+e.mod)%e.mod:0>r?0:e.max<r?e.max:r)}function e(n){var t=l(),e=t._rgba=[];return n=n.toLowerCase(),h(u,function(r,o){var a,s=o.re.exec(n),i=s&&o.parse(s),u=o.space||"rgba";return i?(a=t[u](i),t[c[u].cache]=a[c[u].cache],e=t._rgba=a._rgba,
vendor: 4,195 bytes, line 2366
2366!1):void 0}),e.length?("0,0,0,0"===e.join()&&r.extend(e,a.transparent),t):a[n]}function o(r,n,t){return t=(t+1)%1,1>6*t?r+(n-r)*t*6:1>2*t?n:2>3*t?r+(n-r)*(2/3-t)*6:r}var a,s="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",i=/^([\-+])=\s*(\d+\.?\d*)/,u=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(r){return[r[1],r[2],r[3],r[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(r){return[2.55*r[1],2.55*r[2],2.55*r[3],r[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(r){return[parseInt(r[1],16),parseInt(r[2],16),parseInt(r[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(r){return[parseInt(r[1]+r[1],16),parseInt(r[2]+r[2],16),parseInt(r[3]+r[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(r){return[r[1],r[2]/100,r[3]/100,r[4]]}}],l=r.Color=function(n,t,e,o){return new r.Color.fn.parse(n,t,e,o)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},f={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},p=l.support={},d=r("<p>")[0],h=r.each;d.style.cssText="background-color:rgba(1,1,1,.5)",p.rgba=d.style.backgroundColor.indexOf("rgba")>-1,h(c,function(r,n){n.cache="_"+r,n.props.alpha={idx:3,type:"percent",def:1}}),l.fn=r.extend(l.prototype,{parse:function(o,s,i,u){if(o===n)return this._rgba=[null,null,null,null],this;(o.jquery||o.nodeType)&&(o=r(o).css(s),s=n);var f=this,p=r.type(o),d=this._rgba=[];return s!==n&&(o=[o,s,i,u],p="array"),"string"===p?this.parse(e(o)||a._default):"array"===p?(h(c.rgba.props,function(r,n){d[n.idx]=t(o[n.idx],n)}),this):"object"===p?(o instanceof l?h(c,function(r,n){o[n.cache]&&(f[n.cache]=o[n.cache].slice())}):h(c,function(n,e){var a=e.cache;h(e.props,function(r,n){if(!f[a]&&e.to){if("alpha"===r||null==o[r])return;f[a]=e.to(f._rgba)}f[a][n.idx]=t(o[r],n,!0)}),f[a]&&r.inArray(null,f[a].slice(0,3))<0&&(f[a][3]=1,e.from&&(f._rgba=e.from(f[a])))}),this):void 0},is:function(r){var n=l(r),t=!0,e=this;return h(c,function(r,o){var a,s=n[o.cache];return s&&(a=e[o.cache]||o.to&&o.to(e._rgba)||[],h(o.props,function(r,n){return null!=s[n.idx]?t=s[n.idx]===a[n.idx]:void 0})),t}),t},_space:function(){var r=[],n=this;return h(c,function(t,e){n[e.cache]&&r.push(t)}),r.pop()},transition:function(r,n){var e=l(r),o=e._space(),a=c[o],s=0===this.alpha()?l("transparent"):this,i=s[a.cache]||a.to(s._rgba),u=i.slice();return e=e[a.cache],h(a.props,function(r,o){var a=o.idx,s=i[a],l=e[a],c=f[o.type]||{};null!==l&&(null===s?u[a]=l:(c.mod&&(l-s>c.mod/2?s+=c.mod:s-l>c.mod/2&&(s-=c.mod)),u[a]=t((l-s)*n+s,o)))}),this[o](u)},blend:function(n){if(1===this._rgba[3])return this;var t=this._rgba.slice(),e=t.pop(),o=l(n)._rgba;return l(r.map(t,function(r,n){return(1-e)*o[n]+e*r}))},toRgbaString:function(){var n="rgba(",t=r.map(this._rgba,function(r,n){return null==r?n>2?1:0:r});return 1===t[3]&&(t.pop(),n="rgb("),n+t.join()+")"},toHslaString:function(){var n="hsla(",t=r.map(this.hsla(),function(r,n){return null==r&&(r=n>2?1:0),n&&3>n&&(r=Math.round(100*r)+"%"),r});return 1===t[3]&&(t.pop(),n="hsl("),n+t.join()+")"},toHexString:function(n){var t=this._rgba.slice(),e=t.pop();return n&&t.push(~~(255*e)),"#"+r.map(t,function(r){return r=(r||0).toString(16),1===r.length?"0"+r:r}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,c.hsla.to=function(r){if(null==r[0]||null==r[1]||null==r[2])return[null,null,null,r[3]];var n,t,e=r[0]/255,o=r[1]/255,a=r[2]/255,s=r[3],i=Math.max(e,o,a),u=Math.min(e,o,a),l=i-u,c=i+u,f=.5*c;return n=u===i?0:e===i?60*(o-a)/l+360:o===i?60*(a-e)/l+120:60*(e-o)/l+240,t=0===l?0:.5>=f?l/c:l/(2-c),[Math.round(n)%360,t,f,null==s?1:s]},c.hsla.from=function(r){if(null==r[0]||null==r[1]||null==r[2])return[null,
2366null,null,r[3]];var n=r[0]/360,t=r[1],e=r[2],a=r[3],s=.5>=e?e*(1+t):e+t-e*t,i=2*e-s;return[Math.round(255*o(i,s,n+1/3)),Math.round(255*o(i,s,n)),Math.round(255*o(i,s,n-1/3)),a]},h(c,function(e,o){var a=o.props,s=o.cache,u=o.to,c=o.from;l.fn[e]=function(e){if(u&&!this[s]&&(this[s]=u(this._rgba)),e===n)return this[s].slice();var o,i=r.type(e),f="array"===i||"object"===i?e:arguments,p=this[s].slice();return h(a,function(r,n){var e=f["object"===i?r:n.idx];null==e&&(e=p[n.idx]),p[n.idx]=t(e,n)}),c?(o=l(c(p)),o[s]=p,o):l(p)},h(a,function(n,t){l.fn[n]||(l.fn[n]=function(o){var a,s=r.type(o),u="alpha"===n?this._hsla?"hsla":"rgba":e,l=this[u](),c=l[t.idx];return"undefined"===s?c:("function"===s&&(o=o.call(this,c),s=r.type(o)),null==o&&t.empty?this:("string"===s&&(a=i.exec(o),a&&(o=c+parseFloat(a[2])*("+"===a[1]?1:-1))),l[t.idx]=o,this[u](l)))})})}),l.hook=function(n){var t=n.split(" ");h(t,function(n,t){r.cssHooks[t]={set:function(n,o){var a,s,i="";if("transparent"!==o&&("string"!==r.type(o)||(a=e(o)))){if(o=l(a||o),!p.rgba&&1!==o._rgba[3]){for(s="backgroundColor"===t?n.parentNode:n;(""===i||"transparent"===i)&&s&&s.style;)try{i=r.css(s,"backgroundColor"),s=s.parentNode}catch(u){}o=o.blend(i&&"transparent"!==i?i:"_default")}o=o.toRgbaString()}try{n.style[t]=o}catch(u){}}},r.fx.step[t]=function(n){n.colorInit||(n.start=l(n.elem,t),n.end=l(n.end),n.colorInit=!0),r.cssHooks[t].set(n.elem,n.start.transition(n.end,n.pos))}})},l.hook(s),r.cssHooks.borderColor={expand:function(r){var n={};return h(["Top","Right","Bottom","Left"],function(t,e){n["border"+e+"Color"]=r}),n}},a=r.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery);
2367
2368
2369/** -------------- SOME GENERAL FUNCTIONS ---------------------*/
2370
2371/**
2372 * ismouseover function - check if the mouse over some object
2373 */
2374!function(t){function e(){try{var i=this===document?t(this):t(this).contents();}catch(error){return(false);}i.mousemove(function(e){t.mlp={x:e.pageX,y:e.pageY}}),i.find("iframe").on("load",e)}t.mlp={x:0,y:0},t(e),t.fn.ismouseover=function(){var e=!1;return this.eq(0).each(function(){var i=t(this).is("iframe")?t(this).contents().find("body"):t(this),n=i.offset();e=n.left<=t.mlp.x&&n.left+i.outerWidth()>t.mlp.x&&n.top<=t.mlp.y&&n.top+i.outerHeight()>t.mlp.y}),e}}(jQuery);
2375
2376
2377
2378function UGThumbsGeneral(){
2379	
2380	var t = this, g_objThis = jQuery(t);
2381	
2382	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objects, g_objWrapper; 
2383	var g_arrItems, g_objStrip, g_objParent;
2384	var g_functions = new UGFunctions();
2385	var g_strip;
2386	var outer_options;
2387	
2388	this.type = {
2389			GET_THUMBS_ALL: "all",
2390			GET_THUMBS_RATIO: "ratio",
2391			GET_THUMBS_NO_RATIO: "no_ratio",
2392			GET_THUMBS_NEW:"new"
2393	};
2394	
2395	this.events = {		
2396		SETOVERSTYLE: "thumbmouseover",
2397		SETNORMALSTYLE: "thumbmouseout",
2398		SETSELECTEDSTYLE: "thumbsetselected",
2399		
2400		PLACEIMAGE: "thumbplaceimage",
2401		AFTERPLACEIMAGE: "thumb_after_place_image",
2402		IMAGELOADERROR: "thumbimageloaderror",
2403		THUMB_IMAGE_LOADED: "thumb_image_loaded"
2404	};
2405	
2406	var g_options = {
2407			thumb_width:88,								//thumb width
2408			thumb_height:50,							//thumb height
2409			thumb_fixed_size: true,						//true,false - fixed/dynamic thumbnail width
2410			thumb_resize_by: "height",					//set resize by width or height of the image in case of non fixed size, 
2411			
2412			thumb_border_effect:true,					//true, false - specify if the thumb has border
2413			thumb_border_width: 0,						//thumb border width
2414			thumb_border_color: "#000000",				//thumb border color
2415			thumb_over_border_width: 0,					//thumb border width in mouseover state
2416			thumb_over_border_color: "#d9d9d9",			//thumb border color in mouseover state
2417			thumb_selected_border_width: 1,				//thumb width in selected state
2418			thumb_selected_border_color: "#d9d9d9",		//thumb border color in selected state
2419			
2420			thumb_round_corners_radius:0,				//thumb border radius
2421			
2422			thumb_color_overlay_effect: true,			//true,false - thumb color overlay effect, release the overlay on mouseover and selected states
2423			thumb_overlay_color: "#000000",				//thumb overlay color
2424			thumb_overlay_opacity: 0.4,					//thumb overlay color opacity
2425			thumb_overlay_reverse:false,				//true,false - reverse the overlay, will be shown on selected state only
2426			
2427			thumb_image_overlay_effect: false,			//true,false - images orverlay effect on normal state only
2428			thumb_image_overlay_type: "bw",				//bw , blur, sepia - the type of image effect overlay, black and white, sepia and blur.
2429			
2430			thumb_transition_duration: 200,				//thumb effect transition duration
2431			thumb_transition_easing: "easeOutQuad",		//thumb effect transition easing
2432			
2433			thumb_show_loader: true,					//show thumb loader while loading the thumb
2434			thumb_loader_type: "dark",					//dark, light - thumb loader type
2435			
2436			thumb_wrapper_as_link: false,				//set thumb as link
2437			thumb_link_newpage: false					//set the link to open newpage
2438		}
2439	
2440		var g_temp = {
2441			touchEnabled: false,
2442			num_thumbs_checking:0,
2443			customThumbs:false,
2444			funcSetCustomThumbHtml:null,
2445			isEffectBorder: false,
2446			isEffectOverlay: false,
2447			isEffectImage: false,
2448			colorOverlayOpacity: 1,
2449			thumbInnerReduce: 0,
2450			allowOnResize: true,		//allow onresize event
2451			classNewThumb: "ug-new-thumb"
2452		};
2453		
2454	
2455		var g_serviceParams = {			//service variables	
2456			timeout_thumb_check:100,
2457			thumb_max_check_times:600,	//60 seconds
2458			eventSizeChange: "thumb_size_change"
2459		};
2460
2461		/**
2462		 * init the thumbs object
2463		 */
2464		this.init = function(gallery, customOptions){
2465			g_objects = gallery.getObjects();
2466			g_gallery = gallery;
2467			g_objGallery = jQuery(gallery);
2468			g_objWrapper = g_objects.g_objWrapper;
2469			g_arrItems = g_objects.g_arrItems;
2470
2471			g_options = jQuery.extend(g_options, customOptions);
2472
2473			//set effects vars:
2474			g_temp.isEffectBorder = g_options.thumb_border_effect;
2475			g_temp.isEffectOverlay = g_options.thumb_color_overlay_effect;
2476			g_temp.isEffectImage = g_options.thumb_image_overlay_effect;
2477		
2478		}
2479		
2480		this._____________EXTERNAL_SETTERS__________ = function(){};
2481		
2482		
2483		/**
2484		 * append html from item
2485		 */
2486		function appendHtmlThumbFromItem(itemIndex, imageEffectClass){
2487			
2488			var objItem = g_arrItems[itemIndex];
2489			 
2490			 var classAddition = "";
2491			 if(g_temp.customThumbs == false)
2492				 classAddition = " ug-thumb-generated";
2493			
2494			var zIndex = objItem.index + 1;
2495			var thumbStyle = "style='z-index:"+zIndex+";'";
2496			
2497		 	var htmlThumb = "<div class='ug-thumb-wrapper"+classAddition+"' " + thumbStyle + "></div>";
2498
2499			 if(g_options.thumb_wrapper_as_link == true){
2500				 var urlLink = objItem.link;
2501				 if(objItem.link == "")
2502					 urlLink = "javascript:void(0)";
2503				
2504				 var linkTarget = "";
2505					if(g_options.thumb_link_newpage == true && objItem.link)
2506						linkTarget = " target='_blank'";
2507				 
2508				 var htmlThumb = "<a href='" + urlLink + "'"+linkTarget+" class='ug-thumb-wrapper"+classAddition+"'></a>";
2509			 }
2510			 
2511			 var objThumbWrapper = jQuery(htmlThumb);
2512			 
2513			 var objImage = objItem.objThumbImage;
2514			
2515			 if(g_temp.customThumbs == false){
2516				 
2517				 if(g_options.thumb_show_loader == true && objImage){
2518					 
2519					 var loaderClass = "ug-thumb-loader-dark";
2520					 if(g_options.thumb_loader_type == "bright")
2521						 loaderClass = "ug-thumb-loader-bright";
2522					 
2523					 objThumbWrapper.append("<div class='ug-thumb-loader " + loaderClass + "'></div>");
2524					 objThumbWrapper.append("<div class='ug-thumb-error' style='display:none'></div>");
2525				 }
2526				 					 
2527				 if(objImage){
2528					 objImage.addClass("ug-thumb-image");
2529					 
2530					 //if image overlay effects active, clone the image, and set the effects class on it
2531					 if(g_options.thumb_image_overlay_effect == true){
2532						var objImageOverlay = objImage.clone().appendTo(objThumbWrapper);
2533						
2534						objImageOverlay.addClass("ug-thumb-image-overlay " + imageEffectClass).removeClass("ug-thumb-image");
2535						objImageOverlay.fadeTo(0,0);
2536						objItem.objImageOverlay = objImageOverlay;
2537					 }
2538							 
2539					 objThumbWrapper.append(objImage);
2540				 }
2541				 
2542			 }//end if not custom thumb
2543			 
2544			 if(g_temp.isEffectBorder)
2545				 objThumbWrapper.append("<div class='ug-thumb-border-overlay'></div>");
2546			 
2547			 if(g_temp.isEffectOverlay)
2548				 objThumbWrapper.append("<div class='ug-thumb-overlay'></div>");
2549			 
2550			 g_objParent.append(objThumbWrapper);
2551
2552			 //only custom thumbs function
2553			 if(g_temp.customThumbs){
2554				 
2555				 g_temp.funcSetCustomThumbHtml(objThumbWrapper, objItem);
2556				 
2557			 }
2558			 
2559			 //add thumb wrapper object to items array
2560			 g_arrItems[itemIndex].objThumbWrapper = objThumbWrapper;
2561			
2562			 return(objThumbWrapper);
2563		}
2564		
2565		
2566		/**
2567		 * append the thumbs html to some parent
2568		 */
2569		this.setHtmlThumbs = function(objParent, isAppend){
2570			
2571			g_objParent = objParent;
2572			
2573			//set image effect class
2574			if(g_temp.isEffectImage == true){
2575				var imageEffectClass = getImageEffectsClass();
2576			}
2577			
2578			if(isAppend !== true){		//set all thumbs
2579				var numItems = g_gallery.getNumItems();
2580				
2581				 //append thumbs to strip
2582				 for(var i=0;i<numItems;i++){
2583					 appendHtmlThumbFromItem(i, imageEffectClass);
2584				 }
2585				
2586			}else{		//append only new items, mark only new added thumbs as new thumbs
2587				
2588				var objThumbs = t.getThumbs();
2589				
2590				objThumbs.removeClass(g_temp.classNewThumb);
2591				
2592				var arrNewIndexes = g_gallery.getNewAddedItemsIndexes();
2593				
2594				 jQuery.each(arrNewIndexes,function(i,itemIndex){
2595					 
2596					 var objThumbWrapper = appendHtmlThumbFromItem(itemIndex, imageEffectClass);
2597					 objThumbWrapper.addClass(g_temp.classNewThumb);
2598					 
2599				 });
2600				 					
2601			}
2602			
2603			 
2604		}
2605
2606		
2607		function _______________SETTERS______________(){};
2608
2609		
2610		/**
2611		 * set thumb size with all the inside components (without the image).
2612		 * else, set to all the thumbs
2613		 */
2614		function setThumbSize(width, height, objThumb, innerOnly){
2615			
2616			var objCss = {
2617				width: width+"px",
2618				height: height+"px"
2619			};
2620			
2621			var objCssInner = {
2622					width: width-g_temp.thumbInnerReduce+"px",
2623					height: height-g_temp.thumbInnerReduce+"px"
2624				};
2625			
2626			var selectorsString = ".ug-thumb-loader, .ug-thumb-error, .ug-thumb-border-overlay, .ug-thumb-overlay";
2627			
2628			//set thumb size
2629			if(objThumb){
2630				if(innerOnly !== true)
2631					objThumb.css(objCss);
2632				
2633				objThumb.find(selectorsString).css(objCssInner);
2634			}
2635			else{	//set to all items
2636				g_objParent.children(".ug-thumb-wrapper").css(objCss);
2637				g_objParent.find(selectorsString).css(objCssInner);
2638			}
2639			
2640		}
2641
2642		
2643		/**
2644		 * set thumb border effect
2645		 */
2646		function setThumbBorderEffect(objThumb, borderWidth, borderColor, noAnimation){
2647						
2648			if(!noAnimation)
2649				var noAnimation = false;
2650			
2651			if(g_gallery.isFakeFullscreen())
2652				noAnimation = true;
2653			
2654			var objBorderOverlay = objThumb.children(".ug-thumb-border-overlay");
2655			
2656			//set the border to thumb and not to overlay if no border size transition
2657			/*
2658			if(g_options.thumb_border_width == g_options.thumb_over_border_width
2659				&& g_options.thumb_border_width == g_options.thumb_selected_border_width)
2660				objBorderOverlay = objThumb;
2661			*/
2662			
2663			var objCss = {};
2664			
2665			objCss["border-width"] = borderWidth + "px";
2666			
2667			if(borderWidth != 0)
2668				objCss["border-color"] = borderColor;
2669			
2670			if(noAnimation && noAnimation === true){
2671				objBorderOverlay.css(objCss);
2672				
2673				if(borderWidth == 0)
2674					objBorderOverlay.hide();
2675				else
2676					objBorderOverlay.show();
2677			}
2678			else{
2679				
2680				if(borderWidth == 0)
2681					objBorderOverlay.stop().fadeOut(g_options.thumb_transition_duration);
2682				else
2683					objBorderOverlay.show().stop().fadeIn(g_options.thumb_transition_duration);
2684				
2685				animateThumb(objBorderOverlay, objCss);
2686			}
2687		
2688		}
2689		
2690		
2691		/**
2692		 * set thumb border effect
2693		 */
2694		function setThumbColorOverlayEffect(objThumb, isActive, noAnimation){
2695			
2696			var objOverlay = objThumb.children(".ug-thumb-overlay");
2697			
2698			var animationDuration = g_options.thumb_transition_duration;
2699			if(noAnimation && noAnimation === true)
2700				animationDuration = 0;
2701			
2702			if(isActive){
2703				objOverlay.stop(true).fadeTo(animationDuration, g_temp.colorOverlayOpacity);
2704			}else{
2705				objOverlay.stop(true).fadeTo(animationDuration, 0);
2706			}
2707			
2708		}
2709		
2710		
2711		/**
2712		 * set thumbnail bw effect
2713		 */
2714		function setThumbImageOverlayEffect(objThumb, isActive, noAnimation){
2715			
2716			var objImage = objThumb.children("img.ug-thumb-image");
2717			var objImageOverlay = objThumb.children("img.ug-thumb-image-overlay");
2718					
2719			var animationDuration = g_options.thumb_transition_duration;
2720			if(noAnimation && noAnimation === true)
2721				animationDuration = 0;
2722						
2723			if(isActive){
2724				objImageOverlay.stop(true).fadeTo(animationDuration,1);
2725			}else{
2726				//show the image, hide the overlay
2727				objImage.fadeTo(0,1);
2728				objImageOverlay.stop(true).fadeTo(animationDuration,0);
2729			}
2730			
2731		}
2732		
2733		
2734		/**
2735		 * on thumb mouse out - return the thumb style to original
2736		 */
2737		this.setThumbNormalStyle = function(objThumb, noAnimation, fromWhere){
2738			
2739			if(g_temp.customThumbs == true){
2740				objThumb.removeClass("ug-thumb-over");
2741			}
2742			
2743			if(g_temp.isEffectBorder)
2744			  setThumbBorderEffect(objThumb, g_options.thumb_border_width, g_options.thumb_border_color, noAnimation);
2745			
2746			if(g_temp.isEffectOverlay){
2747				var isSet = (g_options.thumb_overlay_reverse == true)?false:true;
2748				setThumbColorOverlayEffect(objThumb, isSet, noAnimation);
2749			}
2750						
2751			if(g_temp.isEffectImage){
2752				setThumbImageOverlayEffect(objThumb, true, noAnimation);
2753			}
2754			
2755			g_objThis.trigger(t.events.SETNORMALSTYLE, objThumb);
2756		}
2757		
2758		
2759		/**
2760		 * on thumb mouse over - turn thumb style to over position
2761		 */
2762		this.setThumbOverStyle = function(objThumb){
2763			
2764			if(g_temp.customThumbs == true){
2765				objThumb.addClass("ug-thumb-over");
2766			}
2767			
2768			//border effect
2769			if(g_temp.isEffectBorder)
2770				setThumbBorderEffect(objThumb, g_options.thumb_over_border_width, g_options.thumb_over_border_color);
2771			
2772			//color overlay effect 
2773			if(g_temp.isEffectOverlay){
2774				var isSet = (g_options.thumb_overlay_reverse == true)?true:false;
2775				setThumbColorOverlayEffect(objThumb, isSet);
2776			}
2777			
2778			//image overlay effect
2779			if(g_temp.isEffectImage == true){
2780				setThumbImageOverlayEffect(objThumb, false);
2781			}
2782			
2783			//trigger event for parent classes
2784			g_objThis.trigger(t.events.SETOVERSTYLE, objThumb);
2785		}
2786		
2787		
2788		/**
2789		 * set thumb selected style
2790		 */
2791		function setThumbSelectedStyle(objThumb, noAnimation){
2792						
2793			if(g_temp.isEffectBorder)			
2794				setThumbBorderEffect(objThumb, g_options.thumb_selected_border_width, g_options.thumb_selected_border_color, noAnimation);
2795			
2796			if(g_temp.isEffectOverlay){
2797				var isSet = (g_options.thumb_overlay_reverse == true)?true:false;
2798				setThumbColorOverlayEffect(objThumb, isSet, noAnimation);
2799			}
2800			
2801			//image overlay effect
2802			if(g_temp.isEffectImage)
2803				setThumbImageOverlayEffect(objThumb, false, noAnimation);
2804
2805			
2806			g_objThis.trigger(t.events.SETSELECTEDSTYLE, objThumb);
2807
2808		}
2809		
2810		
2811		/**
2812		 * set loading error of the thumb
2813		 */
2814		function setItemThumbLoadedError(objThumb){
2815			
2816			var objItem = t.getItemByThumb(objThumb);
2817			
2818			objItem.isLoaded = true;
2819			objItem.isThumbImageLoaded = false;		
2820			
2821			if(g_temp.customThumbs == true){
2822				
2823				g_objThis.trigger(t.events.IMAGELOADERROR, objThumb);
2824				return(true);
2825			
2826			}
2827			
2828			objThumb.children(".ug-thumb-loader").hide();
2829			objThumb.children(".ug-thumb-error").show();		
2830		}
2831		
2832		
2833		/**
2834		 * set border radius of all the thmbs
2835		 */
2836		function setThumbsBorderRadius(objThumbs){
2837						
2838			if(g_options.thumb_round_corners_radius <= 0)
2839				return(false);
2840			
2841			//set radius:
2842			var objCss = {
2843				"border-radius":g_options.thumb_round_corners_radius + "px"
2844			};
2845			
2846			if(objThumbs){
2847				objThumbs.css(objCss);
2848				objThumbs.find(".ug-thumb-border-overlay").css(objCss);
2849			}else{
2850				g_objParent.find(".ug-thumb-wrapper, .ug-thumb-wrapper .ug-thumb-border-overlay").css(objCss);
2851			}
2852			
2853		}
2854		
2855		
2856		/**
2857		 * animate thumb transitions
2858		 */
2859		function animateThumb(objThumb, objThumbCss){
2860			
2861			objThumb.stop(true).animate(objThumbCss ,{
2862				duration: g_options.thumb_transition_duration,
2863				easing: g_options.thumb_transition_easing,
2864				queue: false
2865			});
2866					
2867		}
2868		
2869		
2870		/**
2871		 * redraw the thumb style according the state
2872		 */
2873		function redrawThumbStyle(objThumb){
2874
2875			if(isThumbSelected(objThumb) == true)
2876				setThumbSelectedStyle(objThumb, true, "redraw");
2877			else
2878				t.setThumbNormalStyle(objThumb, true, "redraw");
2879		}
2880		
2881		
2882		
2883		
2884		/**
2885		 * place thumb image
2886		 * retrun - false, if already loaded
2887		 * return true - if was set on this function
2888		 * isForce - set the image anyway
2889		 */
2890		function placeThumbImage(objThumb, objImage, objItem){
2891			
2892			//scale the image
2893			if(g_options.thumb_fixed_size == true){
2894				g_functions.scaleImageCoverParent(objImage, objThumb);
2895			}
2896			else{
2897				
2898				//variant size
2899				
2900				if(g_options.thumb_resize_by == "height")	//horizontal strip
2901					g_functions.scaleImageByHeight(objImage, g_options.thumb_height);
2902				else		//vertical strip
2903					g_functions.scaleImageByWidth(objImage, g_options.thumb_width);
2904				
2905				var imageSize = g_functions.getElementSize(objImage);
2906				g_functions.placeElement(objImage, 0, 0);
2907				setThumbSize(imageSize.width, imageSize.height, objThumb);
2908				
2909			}
2910			
2911			//hide loader
2912			objThumb.children(".ug-thumb-loader").hide();
2913			
2914			//show image
2915			objImage.show();
2916			
2917			//if overlay effect exists
2918			if(g_options.thumb_image_overlay_effect == false){
2919				objImage.fadeTo(0,1);
2920			}
2921			else{
2922
2923				//place bw image also if exists
2924				if(g_options.thumb_image_overlay_effect == true){
2925					copyPositionToThumbOverlayImage(objImage);
2926				}
2927
2928				//hide the original image (avoid blinking at start)
2929				objImage.fadeTo(0,0);
2930
2931				//redraw the style, because this function can overwrite it
2932				redrawThumbStyle(objThumb);
2933			}
2934			
2935			g_objThis.trigger(t.events.AFTERPLACEIMAGE, objThumb);
2936			
2937		}
2938
2939
2940		
2941		/**
2942		 * copy image position to bw image (if exists)
2943		 */
2944		function copyPositionToThumbOverlayImage(objImage){
2945						
2946			var objImageBW = objImage.siblings(".ug-thumb-image-overlay");
2947			if(objImageBW.length == 0)
2948				return(false);
2949			
2950			var objSize = g_functions.getElementSize(objImage);
2951				
2952			var objCss = {
2953					"width":objSize.width+"px",
2954					"height":objSize.height+"px",
2955					"left":objSize.left+"px",
2956					"top":objSize.top+"px"
2957				}
2958				
2959			objImageBW.css(objCss);
2960			
2961			//show the image
2962			if(g_temp.customThumbs == false)
2963				objImageBW.fadeTo(0,1);
2964			
2965		}
2966		
2967		
2968		
2969		
2970		function _______________GETTERS______________(){};
2971		
2972		
2973		/**
2974		 * get the image effects class from the options
2975		 */
2976		function getImageEffectsClass(){
2977			
2978			var imageEffectClass = "";
2979			var arrEffects = g_options.thumb_image_overlay_type.split(",");
2980			
2981			for(var index in arrEffects){
2982				var effect = arrEffects[index];
2983				
2984				switch(effect){
2985					case "bw":
2986						imageEffectClass += " ug-bw-effect";
2987					break;
2988					case "blur":
2989						imageEffectClass += " ug-blur-effect";
2990					break; 
2991					case "sepia":
2992						imageEffectClass += " ug-sepia-effect";
2993					break;
2994				}
2995			}
2996					
2997			return(imageEffectClass);
2998		}
2999
3000		/**
3001		 * get if the thumb is selected
3002		 */
3003		function isThumbSelected(objThumbWrapper){
3004			
3005			if(objThumbWrapper.hasClass("ug-thumb-selected"))
3006				return(true);
3007			
3008			return(false);
3009		}
3010
3011		
3012		function _______________EVENTS______________(){};
3013		
3014		/**
3015		 * on thumb size change - triggered by parent on custom thumbs type
3016		 */
3017		function onThumbSizeChange(temp, objThumb){
3018			
3019			objThumb = jQuery(objThumb);
3020			var objItem = t.getItemByThumb(objThumb);
3021			
3022			var objSize = g_functions.getElementSize(objThumb);
3023			
3024			setThumbSize(objSize.width, objSize.height, objThumb, true);
3025			
3026			redrawThumbStyle(objThumb);
3027		}
3028		
3029		
3030		/**
3031		 * on thumb mouse over
3032		 */
3033		function onMouseOver(objThumb){
3034			
3035			
3036			//if touch enabled unbind event
3037			if(g_temp.touchEnabled == true){
3038				objThumbs.off("mouseenter").off("mouseleave");
3039				return(true);
3040			}
3041			
3042			if(isThumbSelected(objThumb) == false)
3043				t.setThumbOverStyle(objThumb);
3044			
3045		}
3046		
3047		
3048		/**
3049		 * on thumb mouse out
3050		 */
3051		function onMouseOut(objThumb){
3052			
3053			if(g_temp.touchEnabled == true)
3054				return(true);
3055							
3056			if(isThumbSelected(objThumb) == false)
3057				t.setThumbNormalStyle(objThumb, false);
3058		}
3059		
3060		
3061		/**
3062		 * on image loaded event
3063		 */
3064		function onImageLoaded(image, isForce){
3065
3066			if(!isForce)
3067				var isForce = false;
3068			
3069			var objImage = jQuery(image);
3070			var objThumb = objImage.parents(".ug-thumb-wrapper");
3071			
3072			if(objThumb.parent().length == 0)		//don't treat detached thumbs
3073				return(false);
3074						
3075			objItem = t.getItemByThumb(objThumb);
3076			
3077			if(objItem.isLoaded == true && isForce === false)
3078				return(false);
3079			
3080			t.triggerImageLoadedEvent(objThumb, objImage);
3081			
3082			if(g_temp.customThumbs == true){
3083				
3084				g_objThis.trigger(t.events.PLACEIMAGE, [objThumb, objImage]);
3085			
3086			}else{
3087				
3088				placeThumbImage(objThumb, objImage, objItem);
3089				
3090			}
3091			
3092		}
3093		
3094		
3095		/**
3096		 * on image loaded - set appropriete item vars
3097		 */
3098		function onThumbImageLoaded(data, objThumb, objImage){
3099						
3100			objItem = t.getItemByThumb(objThumb);
3101						
3102			objItem.isLoaded = true;
3103			objItem.isThumbImageLoaded = true;
3104			
3105			var objSize = g_functions.getImageOriginalSize(objImage);
3106						
3107			objItem.thumbWidth = objSize.width;
3108			objItem.thumbHeight = objSize.height;
3109			objItem.thumbRatioByWidth = objSize.width / objSize.height;
3110			objItem.thumbRatioByHeight = objSize.height / objSize.width;
3111			
3112			objThumb.addClass("ug-thumb-ratio-set");
3113			
3114		}
3115
3116		
3117		/**
3118		 * set thumbnails html properties
3119		 */
3120		this.setHtmlProperties = function(objThumbs){
3121			
3122			if(!objThumbs)
3123				var objThumbs = t.getThumbs();
3124			
3125			//set thumb params
3126			if(g_temp.customThumbs == false){
3127				var objThumbCss = {};
3128			
3129				//set thumb fixed size
3130				if(g_options.thumb_fixed_size == true)
3131					setThumbSize(g_options.thumb_width, g_options.thumb_height, objThumbs);
3132				
3133				 setThumbsBorderRadius(objThumbs);
3134			}
3135			 
3136			 //set normal style to all the thumbs
3137			objThumbs.each(function(){
3138				 var objThumb = jQuery(this);
3139				 redrawThumbStyle(objThumb);
3140			 });
3141			
3142
3143			//set color. if empty set from css
3144			if(g_temp.isEffectOverlay){
3145				
3146				if(g_options.thumb_overlay_color){
3147										
3148					var objCss = {};
3149					if(g_functions.isRgbaSupported()){
3150						var colorRGB = g_functions.convertHexToRGB(g_options.thumb_overlay_color, g_options.thumb_overlay_opacity);
3151						objCss["background-color"] = colorRGB;										
3152					}else{
3153						objCss["background-color"] = g_options.thumb_overlay_color;
3154						g_temp.colorOverlayOpacity = g_options.thumb_overlay_opacity;
3155					}
3156					
3157					objThumbs.find(".ug-thumb-overlay").css(objCss);
3158				}
3159				
3160			}
3161			
3162		}
3163
3164				
3165		/**
3166		 * set the thumb on selected state
3167		 */
3168		this.setThumbSelected = function(objThumbWrapper){
3169			
3170			if(g_temp.customThumbs == true)
3171				objThumbWrapper.removeClass("ug-thumb-over");
3172			
3173			if(isThumbSelected(objThumbWrapper) == true)
3174				return(true);
3175			
3176			objThumbWrapper.addClass("ug-thumb-selected");
3177			
3178			//set thumb selected style
3179			setThumbSelectedStyle(objThumbWrapper);
3180		}
3181		
3182		/**
3183		 * set the thumb unselected state
3184		 */
3185		this.setThumbUnselected = function(objThumbWrapper){
3186			
3187			//remove the selected class
3188			objThumbWrapper.removeClass("ug-thumb-selected");
3189			
3190			t.setThumbNormalStyle(objThumbWrapper, false, "set unselected");
3191		}
3192		
3193		
3194		/**
3195		 * set the options of the strip
3196		 */
3197		this.setOptions = function(objOptions){
3198			
3199			g_options = jQuery.extend(g_options, objOptions);
3200			
3201		}
3202		
3203		
3204		/**
3205		 * set thumb inner reduce - reduce this number when resizing thumb inner
3206		 */
3207		this.setThumbInnerReduce = function(innerReduce){
3208			
3209			g_temp.thumbInnerReduce = innerReduce;
3210			
3211		}
3212		
3213		/**
3214		 * set custom thumbs
3215		 * allowedEffects - border, overlay, image
3216		 */
3217		this.setCustomThumbs = function(funcSetHtml, arrAlowedEffects, customOptions){
3218			
3219			g_temp.customThumbs = true;
3220						
3221			if(typeof funcSetHtml != "function")
3222				throw new Error("The argument should be function");
3223			
3224			
3225			g_temp.funcSetCustomThumbHtml = funcSetHtml;
3226			
3227			//enable effects:
3228			if(jQuery.inArray("overlay", arrAlowedEffects) == -1)
3229				g_temp.isEffectOverlay = false;				
3230			
3231			if(jQuery.inArray("border", arrAlowedEffects) == -1)
3232				g_temp.isEffectBorder = false;
3233			
3234			g_temp.isEffectImage = false;		//for custom effects the image is always off
3235
3236			//check for dissalow onresize
3237			if(customOptions && customOptions.allow_onresize === false){
3238				g_temp.allowOnResize = false;
3239			}
3240		
3241		}
3242		
3243		
3244		
3245		
3246		
3247		
3248		this._____________EXTERNAL_GETTERS__________ = function(){};
3249
3250		/**
3251		 * get the options object
3252		 */
3253		this.getOptions = function(){
3254			
3255			return(g_options);
3256		}
3257		
3258		
3259		/**
3260		 * get num thumbs
3261		 */
3262		this.getNumThumbs = function(){
3263			var numThumbs = g_arrItems.length;
3264			return(numThumbs);
3265		}
3266
3267		
3268		/**
3269		 * get thumb image
3270		 */
3271		this.getThumbImage = function(objThumb){
3272			
3273			var objImage = objThumb.find(".ug-thumb-image");
3274			return(objImage);
3275		}
3276		
3277		
3278		/**
3279		 * get thumbs by index
3280		 */
3281		this.getThumbByIndex = function(index){
3282			var objThumbs = t.getThumbs();
3283			
3284			if(index >= objThumbs.length || index < 0)
3285				throw new Error("Wrong thumb index");
3286			
3287			var objThumb = jQuery(objThumbs[index]);
3288			
3289			return(objThumb);
3290		}
3291		
3292		
3293		/**
3294		 * get all thumbs jquery object
3295		 */
3296		this.getThumbs = function(mode){
3297			
3298			var thumbClass = ".ug-thumb-wrapper";
3299			var classRatio = ".ug-thumb-ratio-set";
3300			
3301			switch(mode){
3302				default:
3303				case t.type.GET_THUMBS_ALL:
3304					var objThumbs = g_objParent.children(thumbClass)
3305				break;
3306				case t.type.GET_THUMBS_NO_RATIO:
3307					var objThumbs = g_objParent.children(thumbClass).not(classRatio);
3308				break;
3309				case t.type.GET_THUMBS_RATIO:
3310					var objThumbs = g_objParent.children(thumbClass + classRatio);
3311				break;
3312				case t.type.GET_THUMBS_NEW:
3313					var objThumbs = g_objParent.children("."+g_temp.classNewThumb);
3314				break;
3315			}
3316			
3317			return(objThumbs);
3318		}
3319		
3320		
3321		/**
3322		 * get item by thumb object
3323		 */
3324		this.getItemByThumb = function(objThumb){
3325			
3326			var index = objThumb.data("index");
3327			
3328			if(index === undefined)
3329				index = objThumb.index();
3330			
3331			var arrItem = g_arrItems[index];
3332			return(arrItem);
3333		}
3334		
3335		
3336		/**
3337		 * is thumb loaded
3338		 */
3339		this.isThumbLoaded = function(objThumb){
3340			
3341			var objItem = t.getItemByThumb(objThumb);
3342			
3343			return(objItem.isLoaded);			
3344		}
3345		
3346		
3347		/**
3348		 * get global thumb size
3349		 */
3350		this.getGlobalThumbSize = function(){
3351			
3352			var objSize = {
3353				width:g_options.thumb_width,
3354				height: g_options.thumb_height
3355			};
3356			
3357			return(objSize);
3358		}
3359		
3360		
3361		this._____________EXTERNAL_OTHERS__________ = function(){};
3362
3363
3364		/**
3365		 * init events
3366		 */
3367		this.initEvents = function(){
3368			
3369			var selectorThumb = ".ug-thumb-wrapper";
3370			
3371			//one time event
3372			if(g_temp.allowOnResize == true)
3373				g_objWrapper.on(g_serviceParams.eventSizeChange, onThumbSizeChange);
3374			
3375			//on image loaded event - for setting the image sizes
3376			g_objThis.on(t.events.THUMB_IMAGE_LOADED, onThumbImageLoaded);
3377									
3378			//thumbs events						
3379			g_objParent.on("touchstart",selectorThumb,function(){
3380				g_temp.touchEnabled = true;
3381				g_objParent.off("mouseenter").off("mouseleave");
3382			});
3383			
3384			g_objParent.on("mouseenter",selectorThumb,function(event){				
3385				var objThumb = jQuery(this);
3386				onMouseOver(objThumb);
3387			});
3388
3389			g_objParent.on("mouseleave",selectorThumb,function(event){
3390				var objThumb = jQuery(this);
3391				onMouseOut(objThumb);
3392			});
3393			
3394			
3395		}
3396		
3397		
3398		/**
3399		 * destroy the thumb element
3400		 */
3401		this.destroy = function(){
3402			
3403			var selectorThumb = ".ug-thumb-wrapper";
3404			
3405			g_objParent.off("touchstart",selectorThumb);
3406			g_objWrapper.off(g_serviceParams.eventSizeChange);
3407			g_objParent.off("mouseenter",selectorThumb);
3408			g_objParent.off("mouseleave",selectorThumb);
3409			g_objThis.off(t.events.THUMB_IMAGE_LOADED);
3410		}
3411		
3412		
3413		/**
3414		 * preload thumbs images and put them into the thumbnails
3415		 */
3416		this.loadThumbsImages = function(){
3417
3418			var objImages = g_objParent.find(".ug-thumb-image");
3419			g_functions.checkImagesLoaded(objImages, null, function(objImage,isError){
3420				
3421				if(isError == false){
3422					onImageLoaded(objImage, true);
3423				}
3424				else{
3425					var objItem = jQuery(objImage).parent();
3426					setItemThumbLoadedError(objItem);										
3427				}
3428			});
3429		}
3430		
3431		
3432		/**
3433		 * trigger image loaded event
3434		 */
3435		this.triggerImageLoadedEvent = function(objThumb, objImage){
3436
3437			g_objThis.trigger(t.events.THUMB_IMAGE_LOADED, [objThumb, objImage]);
3438			
3439		}
3440		
3441		
3442		/**
3443		 * hide thumbs
3444		 */
3445		this.hideThumbs = function(){
3446			
3447			g_objParent.find(".ug-thumb-wrapper").hide();
3448			
3449		}
3450		
3451}
3452
3453/**
3454 * thumbs class
3455 * addon to strip gallery
3456 */
3457function UGThumbsStrip(){
3458
3459	var t = this;
3460	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objects, g_objWrapper; 
3461	var g_arrItems, g_objStrip, g_objStripInner;
3462	var g_aviaControl, g_touchThumbsControl, g_functions = new UGFunctions();	
3463	var g_isVertical = false, g_thumbs = new UGThumbsGeneral();
3464	var g_functions = new UGFunctions();
3465	
3466	var g_options = {
3467		strip_vertical_type: false,
3468		strip_thumbs_align: "left",					//left, center, right, top, middle, bottom - the align of the thumbs when they smaller then the strip size.
3469		strip_space_between_thumbs:6,				//space between thumbs
3470		strip_thumb_touch_sensetivity:15,  			//from 1-100, 1 - most sensetive, 100 - most unsensetive
3471		strip_scroll_to_thumb_duration:500,			//duration of scrolling to thumb
3472		strip_scroll_to_thumb_easing:"easeOutCubic",		//easing of scrolling to thumb animation
3473		strip_control_avia:true,					//avia control - move the strip according str
3473ip moseover position
3474		strip_control_touch:true,					//touch control - move the strip by dragging it
3475		strip_padding_top: 0,						//add some space from the top					
3476		strip_padding_bottom: 0,					//add some space from the bottom
3477		strip_padding_left: 0,						//add some space from left
3478		strip_padding_right: 0						//add some space from right
3479	}
3480	
3481	var g_temp = {
3482		isRunOnce:false,
3483		is_placed:false,
3484		isNotFixedThumbs: false,
3485		handle: null
3486	};
3487	
3488	var g_sizes = {
3489		stripSize:0,		//set after position thumbs
3490		stripActiveSize:0,	//strip size without the padding
3491		stripInnerSize:0,	
3492		thumbSize:0,
3493		thumbSecondSize:0	//size of the height and width of the strip
3494	}
3495	
3496	this.events = {		//events variables
3497			STRIP_MOVE:"stripmove",
3498			INNER_SIZE_CHANGE:"size_change"
3499	}	
3500	
3501	//the defaults for vertical align
3502	var g_defaultsVertical = {
3503		strip_thumbs_align: "top",
3504		thumb_resize_by: "width"
3505	}
3506	
3507	
3508	/**
3509	 * set the thumbs strip html
3510	 */	
3511	this.setHtml = function(objParent){
3512		
3513		if(!objParent){
3514			var objParent = g_objWrapper;
3515			if(g_options.parent_container != null)
3516				objParent = g_options.parent_container;			
3517		}
3518				
3519		objParent.append("<div class='ug-thumbs-strip'><div class='ug-thumbs-strip-inner'></div></div>");		 
3520		g_objStrip = objParent.children(".ug-thumbs-strip");
3521		
3522		g_objStripInner = g_objStrip.children(".ug-thumbs-strip-inner");		
3523				
3524		//put the thumbs to inner strip
3525		g_thumbs.setHtmlThumbs(g_objStripInner);
3526		
3527		//hide thumbs on not fixed mode
3528		if(g_temp.isNotFixedThumbs == true)
3529			g_thumbs.hideThumbs();
3530		
3531	}
3532
3533	
3534	function ___________GENERAL___________(){};
3535	
3536	
3537	/**
3538	 * init the strip
3539	 */
3540	function initStrip(gallery, customOptions){
3541		
3542		g_objects = gallery.getObjects();
3543		g_gallery = gallery;
3544		
3545		g_gallery.attachThumbsPanel("strip", t);
3546		
3547		g_objGallery = jQuery(gallery);
3548		g_objWrapper = g_objects.g_objWrapper;
3549		g_arrItems = g_objects.g_arrItems;
3550
3551		g_options = jQuery.extend(g_options, customOptions);
3552		g_isVertical = g_options.strip_vertical_type;
3553		
3554		//set vertical defaults
3555		if(g_isVertical == true){
3556			g_options = jQuery.extend(g_options, g_defaultsVertical);
3557			g_options = jQuery.extend(g_options, customOptions);
3558			
3559			customOptions.thumb_resize_by = "width";
3560		}
3561		
3562		g_thumbs.init(gallery, customOptions);
3563		
3564		onAfterSetOptions();
3565	}
3566	
3567	
3568	/**
3569	 * run this funcion after set options.
3570	 */
3571	function onAfterSetOptions(){
3572
3573		var thumbsOptions = g_thumbs.getOptions();
3574		
3575		g_temp.isNotFixedThumbs = (thumbsOptions.thumb_fixed_size === false);
3576		g_isVertical = g_options.strip_vertical_type;
3577	}
3578	
3579	
3580	/**
3581	 * run the strip
3582	 */
3583	function runStrip(){
3584		
3585		g_thumbs.setHtmlProperties();
3586		
3587		initSizeParams();
3588
3589		fixSize();
3590
3591		positionThumbs();
3592		
3593		//run only once
3594		if(g_temp.isRunOnce == false){
3595
3596			//init thumbs strip touch
3597			if(g_options.strip_control_touch == true){
3598				g_touchThumbsControl = new UGTouchThumbsControl();
3599				g_touchThumbsControl.init(t);
3600			}
3601
3602			//init thumbs strip avia control
3603			if(g_options.strip_control_avia == true){
3604				g_aviaControl = new UGAviaControl();
3605				g_aviaControl.init(t);
3606			}
3607
3608			checkControlsEnableDisable();
3609
3610			g_thumbs.loadThumbsImages();
3611			
3612			initEvents();
3613		}
3614		
3615						
3616		g_temp.isRunOnce = true;
3617
3618	}
3619	
3620	
3621	/**
3622	 * store strip size and strip active size in vars
3623	 * do after all strip size change
3624	 */
3625	function storeStripSize(size){
3626		
3627		g_sizes.stripSize = size;
3628
3629		if(g_isVertical == false)
3630			g_sizes.stripActiveSize = g_sizes.stripSize - g_options.strip_padding_left - g_options.strip_padding_right;
3631		else
3632			g_sizes.stripActiveSize = g_sizes.stripSize - g_options.strip_padding_top - g_options.strip_padding_bottom;
3633			
3634		if(g_sizes.stripActiveSize < 0)
3635			g_sizes.stripActiveSize = 0;
3636
3637	}
3638	
3639	
3640	/**
3641	 * init some size parameters, before size init and after position thumbs
3642	 */
3643	function initSizeParams(){
3644		
3645		//set thumb outer size:
3646		var arrThumbs = g_objStripInner.children(".ug-thumb-wrapper");
3647		var firstThumb = jQuery(arrThumbs[0]);
3648		var thumbsRealWidth = firstThumb.outerWidth();
3649		var thumbsRealHeight = firstThumb.outerHeight();
3650		var thumbs_options = g_thumbs.getOptions();
3651		
3652		if(g_isVertical == false){			//horizontal
3653			
3654			g_sizes.thumbSize = thumbsRealWidth;
3655		
3656			if(thumbs_options.thumb_fixed_size == true){
3657				g_sizes.thumbSecondSize = thumbsRealHeight;
3658			} else {
3659				g_sizes.thumbSecondSize = thumbs_options.thumb_height;
3660			}
3661			
3662			storeStripSize(g_objStrip.width());
3663			g_sizes.stripInnerSize = g_objStripInner.width();
3664		
3665		}else{		//vertical
3666			g_sizes.thumbSize = thumbsRealHeight;
3667			
3668			if(thumbs_options.thumb_fixed_size == true){
3669				g_sizes.thumbSecondSize = thumbsRealWidth;
3670			} else {
3671				g_sizes.thumbSecondSize = thumbs_options.thumb_width;
3672			}
3673			
3674			storeStripSize(g_objStrip.height());
3675
3676			g_sizes.stripInnerSize = g_objStripInner.height();			
3677		}
3678
3679		
3680	}
3681	
3682	
3683
3684	
3685	/**
3686	 * set size of inner strip according the orientation
3687	 */
3688	function setInnerStripSize(innerSize){
3689
3690		if(g_isVertical == false)
3691			g_objStripInner.width(innerSize);
3692		else
3693			g_objStripInner.height(innerSize);
3694			
3695		g_sizes.stripInnerSize = innerSize;
3696		
3697		checkControlsEnableDisable();
3698		
3699		jQuery(t).trigger(t.events.INNER_SIZE_CHANGE);
3700	}
3701	
3702	
3703	/**
3704	 * position thumbnails in the thumbs panel
3705	 */
3706	function positionThumbs(){
3707		
3708		var arrThumbs = g_objStripInner.children(".ug-thumb-wrapper");
3709		
3710		var posx = 0;
3711		var posy = 0;
3712		
3713		if(g_isVertical == false)
3714			posy = g_options.strip_padding_top;
3715		
3716		for (i = 0; i < arrThumbs.length; i++) {
3717			
3718			var objThumb = jQuery(arrThumbs[i]);
3719			
3720			//skip from placing if not loaded yet on non fixed mode
3721			if(g_temp.isNotFixedThumbs == true){
3722				objItem = g_thumbs.getItemByThumb(objThumb);
3723				if(objItem.isLoaded == false)
3724					continue;
3725				
3726				//the thumb is hidden if not placed
3727				objThumb.show();
3728			}
3729			
3730			g_functions.placeElement(objThumb, posx, posy);
3731			
3732			if(g_isVertical == false)
3733				posx += objThumb.outerWidth() + g_options.strip_space_between_thumbs;
3734			else
3735				posy += objThumb.outerHeight() + g_options.strip_space_between_thumbs;
3736		}
3737		
3738		//set strip size, width or height
3739		if(g_isVertical == false)
3740			var innerStripSize = posx - g_options.strip_space_between_thumbs;
3741		else
3742			var innerStripSize = posy - g_options.strip_space_between_thumbs;
3743			
3744		setInnerStripSize(innerStripSize);
3745	}
3746
3747	
3748	
3749	/**
3750	 * fix strip and inner size
3751	 */
3752	function fixSize(){
3753		
3754		if(g_isVertical == false){		//fix horizontal
3755			
3756			var height = g_sizes.thumbSecondSize;
3757			
3758			 var objCssStrip = {};
3759			 objCssStrip["height"] = height+"px";
3760			 		 
3761			 //set inner strip params
3762			 var objCssInner = {};
3763			 objCssInner["height"] = height+"px";
3764
3765		}else{	//fix vertical
3766			
3767			var width = g_sizes.thumbSecondSize;
3768			
3769			 var objCssStrip = {};
3770			 objCssStrip["width"] = width+"px";
3771			 		 
3772			 //set inner strip params
3773			 var objCssInner = {};
3774			 objCssInner["width"] = width+"px";
3775			 
3776		}
3777		 
3778		g_objStrip.css(objCssStrip);
3779		g_objStripInner.css(objCssInner);				
3780	}
3781	
3782	
3783	
3784	/**
3785	 * scroll by some number
3786	 * .
3787	 */
3788	function scrollBy(scrollStep){
3789		
3790		var innerPos = t.getInnerStripPos();
3791		var finalPos = innerPos + scrollStep;
3792		
3793		finalPos = t.fixInnerStripLimits(finalPos);
3794		
3795		t.positionInnerStrip(finalPos, true);		
3796	}
3797	
3798
3799	/**
3800	 * scroll to thumb from min. (left or top) position
3801	 */
3802	function scrollToThumbMin(objThumb){
3803		
3804		var objThumbPos = getThumbPos(objThumb);
3805		
3806		var scrollPos = objThumbPos.min * -1;
3807		scrollPos = t.fixInnerStripLimits(scrollPos);
3808
3809		t.positionInnerStrip(scrollPos, true);
3810	}
3811	
3812	
3813	/**
3814	 * scroll to thumb from max. (right or bottom) position
3815	 */
3816	function scrollToThumbMax(objThumb){
3817		
3818		var objThumbPos = getThumbPos(objThumb);		
3819		
3820		var scrollPos = objThumbPos.max * -1 + g_sizes.stripSize;
3821		scrollPos = t.fixInnerStripLimits(scrollPos);
3822		
3823		t.positionInnerStrip(scrollPos, true);
3824	}
3825
3826	
3827	/**
3828	 * scroll to some thumbnail
3829	 */
3830	function scrollToThumb(objThumb){
3831		
3832		if(isStripMovingEnabled() == false)
3833			return(false);
3834		
3835		var objBounds = getThumbsInsideBounds();
3836		
3837		var objThumbPos = getThumbPos(objThumb);
3838		
3839		if(objThumbPos.min < objBounds.minPosThumbs){			
3840			
3841			var prevThumb = objThumb.prev();
3842			if(prevThumb.length)
3843				scrollToThumbMin(prevThumb);
3844			else 
3845				scrollToThumbMin(objThumb);				
3846			
3847		}else if(objThumbPos.max > objBounds.maxPosThumbs){			
3848			
3849			var nextThumb = objThumb.next();
3850			if(nextThumb.length)
3851				scrollToThumbMax(nextThumb);
3852			else
3853				scrollToThumbMax(objThumb);
3854				
3855		}
3856		
3857	}
3858	
3859	/**
3860	 * scroll to selected thumb
3861	 */
3862	function scrollToSelectedThumb(){
3863		
3864		var selectedItem = g_gallery.getSelectedItem();
3865		if(selectedItem == null)
3866			return(true);
3867		
3868		var objThumb = selectedItem.objThumbWrapper;
3869		if(objThumb)
3870			scrollToThumb(objThumb);
3871		
3872	}
3873	
3874	
3875	
3876	/**
3877	 * check that the inner strip off the limits position, and reposition it if there is a need
3878	 */
3879	function checkAndRepositionInnerStrip(){
3880		if(isStripMovingEnabled() == false)
3881			return(false);
3882		
3883		var pos = t.getInnerStripPos();
3884		
3885		var posFixed = t.fixInnerStripLimits(pos);
3886				
3887		if(pos != posFixed)
3888			t.positionInnerStrip(posFixed, true);
3889	}
3890	
3891	
3892	/**
3893	 * enable / disable controls according inner width (move enabled).
3894	 */
3895	function checkControlsEnableDisable(){
3896		
3897		var isMovingEndbled = isStripMovingEnabled();
3898		
3899		if(isMovingEndbled == true){
3900			
3901			if(g_aviaControl)
3902				g_aviaControl.enable();
3903			
3904			if(g_touchThumbsControl)
3905				g_touchThumbsControl.enable();
3906			
3907		}else{
3908			
3909			if(g_aviaControl)
3910				g_aviaControl.disable();
3911			
3912			if(g_touchThumbsControl)
3913				g_touchThumbsControl.disable();
3914			
3915		}
3916		
3917	}
3918	
3919	/**
3920	 * align inner strip according the options
3921	 */
3922	function alignInnerStrip(){
3923		
3924		if(isStripMovingEnabled())
3925			return(false);
3926		
3927		if(g_isVertical == false)
3928			g_functions.placeElement(g_objStripInner, g_options.strip_thumbs_align, 0);
3929		else
3930			g_functions.placeElement(g_objStripInner, 0, g_options.strip_thumbs_align);
3931			
3932	}
3933	
3934	
3935	function ___________EVENTS___________(){};
3936	
3937	/**
3938	 * on thumb click event. Select the thumb
3939	 */
3940	function onThumbClick(objThumb){
3941
3942		//cancel click event only if passed significant movement
3943		if(t.isTouchMotionActive()){
3944
3945			var isSignificantPassed = g_touchThumbsControl.isSignificantPassed();
3946			if(isSignificantPassed == true)
3947				return(true);
3948		}
3949
3950		//run select item operation
3951		var objItem = g_thumbs.getItemByThumb(objThumb);
3952
3953		g_gallery.selectItem(objItem);
3954	}
3955	
3956	
3957	/**
3958	 * on some thumb placed, run the resize, but with time passed
3959	 */
3960	function onThumbPlaced(){
3961		
3962		clearTimeout(g_temp.handle);
3963		
3964		g_temp.handle = setTimeout(function(){
3965			
3966			positionThumbs();
3967			
3968		},50);
3969			
3970		
3971	}
3972	
3973	/**
3974	 * on item change
3975	 */
3976	function onItemChange(){
3977
3978		var objItem = g_gallery.getSelectedItem();
3979		g_thumbs.setThumbSelected(objItem.objThumbWrapper);
3980		scrollToThumb(objItem.objThumbWrapper);
3981	}
3982	
3983	
3984	/**
3985	 * init panel events
3986	 */
3987	function initEvents(){
3988		
3989		g_thumbs.initEvents();
3990
3991		var objThumbs = g_objStrip.find(".ug-thumb-wrapper");
3992				
3993		objThumbs.on("click touchend", function(event){
3994			
3995			var clickedThumb = jQuery(this);
3996			onThumbClick(clickedThumb);
3997		});
3998		
3999		//on item change, make the thumb selected
4000		g_objGallery.on(g_gallery.events.ITEM_CHANGE, onItemChange);
4001
4002		
4003		//position thumbs after each load on non fixed mode
4004		if(g_temp.isNotFixedThumbs){
4005			
4006			jQuery(g_thumbs).on(g_thumbs.events.AFTERPLACEIMAGE, onThumbPlaced);
4007			
4008		}
4009		
4010	}
4011	
4012	
4013	/**
4014	 * destroy the strip panel events
4015	 */
4016	this.destroy = function(){
4017		
4018		var objThumbs = g_objStrip.find(".ug-thumb-wrapper");
4019		
4020		objThumbs.off("click");
4021		objThumbs.off("touchend");
4022		g_objGallery.off(g_gallery.events.ITEM_CHANGE);
4023
4024		jQuery(g_thumbs).off(g_thumbs.events.AFTERPLACEIMAGE);
4025		
4026		if(g_touchThumbsControl)
4027			g_touchThumbsControl.destroy();
4028		
4029		if(g_aviaControl)
4030			g_aviaControl.destroy();
4031		
4032		g_thumbs.destroy();
4033	}
4034	
4035	
4036	function ____________GETTERS___________(){};
4037		
4038
4039	/**
4040	 * check if the inner width is more then strip width
4041	 */
4042	function isStripMovingEnabled(){
4043		
4044		if(g_sizes.stripInnerSize > g_sizes.stripActiveSize)
4045			return(true);
4046		else
4047			return(false);
4048		
4049	}
4050	
4051	
4052	/**
4053	 * get bounds, if the thumb not in them, it need to be scrolled
4054	 * minPosThumbs, maxPosThumbs - the min and max position that the thumbs should be located to be visible
4055	 */
4056	function getThumbsInsideBounds(){
4057		var obj = {};
4058		var innerPos = t.getInnerStripPos();
4059		
4060		//the 1 is gap that avoid exact bounds
4061		obj.minPosThumbs = innerPos * -1 + 1;				
4062		obj.maxPosThumbs = innerPos * -1 + g_sizes.stripSize - 1;		
4063		
4064		return(obj);
4065	}
4066	
4067	
4068	/**
4069	 * get thumb position according the orientation in the inner strip
4070	 */
4071	function getThumbPos(objThumb){
4072		
4073		var objReturn = {};
4074		
4075		var objPos = objThumb.position();
4076		
4077		if(g_isVertical == false){
4078			objReturn.min = objPos.left;
4079			objReturn.max = objPos.left + g_sizes.thumbSize;
4080		}else{
4081			objReturn.min = objPos.top;
4082			objReturn.max = objPos.top + g_sizes.thumbSize;
4083		}
4084
4085		
4086		return(objReturn);
4087	}
4088	
4089	
4090	
4091	
4092	this.________EXTERNAL_GENERAL___________ = function(){};
4093
4094	/**
4095	 * init function for avia controls
4096	 */
4097	this.init = function(gallery, customOptions){
4098		
4099		initStrip(gallery, customOptions);
4100	}
4101	
4102	
4103	/**
4104	 * set html and properties
4105	 */	
4106	this.run = function(){
4107		runStrip();
4108	}
4109	
4110	
4111	
4112	
4113	/**
4114	* position inner strip on some pos according the orientation
4115	*/
4116	this.positionInnerStrip = function(pos, isAnimate){
4117		
4118		if(isAnimate === undefined)
4119			var isAnimate = false;
4120		
4121		if(g_isVertical == false)
4122			var objPosition = {"left": pos + "px"};
4123		else
4124			var objPosition = {"top": pos + "px"};
4125		
4126		if(isAnimate == false){		//normal position
4127			
4128			g_objStripInner.css(objPosition);
4129			t.triggerStripMoveEvent();
4130		}
4131		else{		//position with animation
4132			
4133			t.triggerStripMoveEvent();
4134			
4135			g_objStripInner.stop(true).animate(objPosition ,{
4136				duration: g_options.strip_scroll_to_thumb_duration,
4137				easing: g_options.strip_scroll_to_thumb_easing,
4138				queue: false,
4139				progress:function(){t.triggerStripMoveEvent()},
4140				always: function(){t.triggerStripMoveEvent()}
4141			});					
4142			
4143		}
4144		
4145	}
4146
4147	/**
4148	 * trigger event - on strip move
4149	 */
4150	this.triggerStripMoveEvent = function(){
4151		
4152		//trigger onstripmove event
4153		jQuery(t).trigger(t.events.STRIP_MOVE);
4154		
4155	}
4156	
4157		
4158	
4159	/**
4160	 * return true if the touch animation or dragging is active
4161	 */
4162	this.isTouchMotionActive = function(){
4163		if(!g_touchThumbsControl)
4164			return(false);
4165		
4166		var isActive = g_touchThumbsControl.isTouchActive();
4167		
4168		return(isActive);
4169	}
4170	
4171	
4172	/**
4173	 * check if thmb item visible, means inside the visible part of the inner strip
4174	 */
4175	this.isItemThumbVisible = function(objItem){
4176		
4177		var objThumb = objItem.objThumbWrapper;
4178		var thumbPos = objThumb.position();
4179		
4180		var posMin = t.getInnerStripPos() * -1;
4181		
4182		if(g_isVertical == false){
4183			var posMax = posMin + g_sizes.stripSize;
4184			var thumbPosMin = thumbPos.left;
4185			var thumbPosMax = thumbPos.left + objThumb.width();			
4186		}else{
4187			var posMax = posMin + g_sizes.stripSize;
4188			var thumbPosMin = thumbPos.top;
4189			var thumbPosMax = thumbPos.top + objThumb.height();			
4190		}
4191				
4192		var isVisible = false;
4193		if(thumbPosMax >= posMin && thumbPosMin <= posMax)
4194			isVisible = true;
4195		
4196		return(isVisible);
4197	}
4198	
4199	/**
4200	 * get inner strip position according the orientation
4201	 */
4202	this.getInnerStripPos = function(){
4203		
4204		if(g_isVertical == false)			
4205			return g_objStripInner.position().left;
4206		else
4207			return g_objStripInner.position().top;
4208	}
4209	
4210	
4211	/**
4212	 * get inner strip limits
4213	 */
4214	this.getInnerStripLimits = function(){
4215		
4216		var output = {};
4217		
4218		if(g_isVertical == false)
4219			output.maxPos = g_options.strip_padding_left;
4220		else
4221			output.maxPos = g_options.strip_padding_top;
4222		
4223		//debugLine(g_sizes.stripActiveSize);
4224		
4225		output.minPos = -(g_sizes.stripInnerSize - g_sizes.stripActiveSize);
4226		
4227		return(output);
4228	}
4229
4230	
4231	/**
4232	 * fix inner position by check boundaries limit
4233	 */
4234	this.fixInnerStripLimits = function(distPos){
4235		
4236		var minPos;
4237		
4238		var objLimits = t.getInnerStripLimits();
4239		
4240		if(distPos > objLimits.maxPos)
4241			distPos = objLimits.maxPos;
4242		
4243		if(distPos < objLimits.minPos)
4244			distPos = objLimits.minPos;
4245		
4246		return(distPos);
4247	}
4248	
4249	
4250	
4251	/**
4252	 * scroll left or down
4253	 */
4254	this.scrollForeward = function(){
4255		scrollBy(-g_sizes.stripSize);
4256	}
4257	
4258	
4259	/**
4260	 * scroll left or down
4261	 */
4262	this.scrollBack = function(){
4263				
4264		scrollBy(g_sizes.stripSize);
4265	}
4266	
4267	
4268	this.________EXTERNAL_SETTERS___________ = function(){};
4269
4270	
4271	/**
4272	 * set the options of the strip
4273	 */
4274	this.setOptions = function(objOptions){
4275		
4276		g_options = jQuery.extend(g_options, objOptions);
4277		
4278		g_thumbs.setOptions(objOptions);
4279		
4280		onAfterSetOptions();
4281	}
4282	
4283	
4284	/**
4285	 * set size of the strip
4286	 * the height size is set automatically from options
4287	 */
4288	this.setSizeVertical = function(height){
4289		
4290		 if(g_isVertical == false){
4291			 throw new Error("setSizeVertical error, the strip size is not vertical");
4292			 return(false);
4293		 }
4294		
4295		 var width = g_sizes.thumbSecondSize;
4296		
4297		 var objCssStrip = {};
4298		 objCssStrip["width"] = width+"px";
4299		 objCssStrip["height"] = height+"px";
4300		 
4301		 g_objStrip.css(objCssStrip);
4302
4303		 storeStripSize(height);
4304		 
4305		 //set inner strip params
4306		 var objCssInner = {};
4307		 objCssInner["width"] = width+"px";
4308		 objCssInner["left"] = "0px";
4309		 objCssInner["top"] = "0px";
4310		 
4311		 g_objStripInner.css(objCssInner);
4312		 
4313		 g_temp.is_placed = true;
4314		 
4315		 checkControlsEnableDisable();
4316	}
4317
4318	
4319	/**
4320	 * set size of the strip
4321	 * the height size is set automatically from options
4322	 */
4323	this.setSizeHorizontal = function(width){
4324				
4325		 if(g_isVertical == true){
4326			 throw new Error("setSizeHorizontal error, the strip size is not horizontal");
4327			 return(false);
4328		 }
4329		
4330		var height = g_sizes.thumbSecondSize + g_options.strip_padding_top + g_options.strip_padding_bottom;
4331		
4332		var objCssStrip = {};
4333		objCssStrip["width"] = width+"px";
4334		objCssStrip["height"] = height+"px";
4335		 
4336		g_objStrip.css(objCssStrip);
4337		
4338		storeStripSize(width);
4339		
4340		var innerLeft = g_options.strip_padding_left;
4341		
4342		 //set inner strip params
4343		 var objCssInner = {};
4344		 objCssInner["height"] = height+"px";
4345		 objCssInner["left"] = innerLeft + "px";
4346		 objCssInner["top"] = "0px";
4347		 
4348		 g_objStripInner.css(objCssInner);
4349		 
4350		 g_temp.is_placed = true;
4351		
4352		 checkControlsEnableDisable();
4353	}
4354	
4355	
4356	/**
4357	 * set position of the strip
4358	 */
4359	this.setPosition = function(left, top, offsetLeft, offsetTop){
4360		g_functions.placeElement(g_objStrip, left, top, offsetLeft, offsetTop);		
4361	}
4362	
4363	
4364	/**
4365	 * resize the panel according the orientation
4366	 */
4367	this.resize = function(newSize){
4368		
4369		if(g_isVertical == false){
4370			
4371			g_objStrip.width(newSize);
4372			g_sizes.stripActiveSize = newSize - g_options.strip_padding_left - g_options.strip_padding_right;
4373
4374		}else{
4375			g_objStrip.height(newSize);
4376			g_sizes.stripActiveSize = newSize - g_options.strip_padding_top - g_options.strip_padding_bottom;
4377		}
4378		
4379		storeStripSize(newSize);
4380		
4381		checkControlsEnableDisable();
4382		
4383		checkAndRepositionInnerStrip();
4384		
4385		alignInnerStrip();
4386		
4387		scrollToSelectedThumb();
4388	}
4389	
4390	
4391	/**
4392	 * set the thumb unselected state
4393	 */
4394	this.setThumbUnselected = function(objThumbWrapper){
4395		
4396		g_thumbs.setThumbUnselected(objThumbWrapper);
4397		
4398	}
4399	
4400	
4401	/**
4402	 * set custom thumbs
4403	 */
4404	this.setCustomThumbs = function(funcSetHtml){
4405		
4406		g_thumbs.setCustomThumbs(funcSetHtml);
4407		
4408	}
4409	
4410	
4411	
4412	
4413	this.________EXTERNAL_GETTERS___________ = function(){};
4414	
4415	/**
4416	 * get objects
4417	 */	
4418	this.getObjects = function(){
4419		
4420		var thumbsOptions = g_thumbs.getOptions();
4421		var commonOpitions = jQuery.extend(g_options, thumbsOptions);
4422		
4423		var obj = {
4424			g_gallery: g_gallery,
4425			g_objGallery: g_objGallery,
4426			g_objWrapper:g_objWrapper,
4427			g_arrItems:g_arrItems,
4428			g_objStrip : g_objStrip,
4429			g_objStripInner : g_objStripInner,
4430			g_aviaControl:g_aviaControl,
4431			g_touchThumbsControl:g_touchThumbsControl,
4432			isVertical: g_isVertical,
4433			g_options: commonOpitions,
4434			g_thumbs: g_thumbs
4435		};
4436		
4437		return(obj);
4438	}
4439	
4440	
4441	/**
4442	 * get thumbs onject
4443	 */
4444	this.getObjThumbs = function(){
4445		
4446		return(g_thumbs);
4447	}
4448	
4449	
4450	/**
4451	 * get selected thumb
4452	 */
4453	this.getSelectedThumb = function(){
4454		
4455		var selectedIndex = g_gallery.getSelectedItemIndex();
4456		if(selectedIndex == -1)
4457			return(null);
4458		
4459		return g_thumbs.getThumbByIndex(selectedIndex);
4460	}
4461	
4462	
4463	/**
4464	 * get strip size and position object
4465	 */
4466	this.getSizeAndPosition = function(){
4467		
4468		var obj = g_functions.getElementSize(g_objStrip);
4469		
4470		return(obj);
4471	}
4472	
4473	/**
4474	 * get thumbs strip height
4475	 */
4476	this.getHeight = function(){
4477		
4478		var stripHeight = g_objStrip.outerHeight();
4479		
4480		return(stripHeight)
4481	}
4482	
4483	
4484	/**
4485	 * get thumbs strip width
4486	 */
4487	this.getWidth = function(){
4488		
4489		var stripWidth = g_objStrip.outerWidth();
4490		
4491		return(stripWidth);
4492	}
4493	
4494	
4495	
4496	/**
4497	 * get all stored sizes object
4498	 */
4499	this.getSizes = function(){
4500		
4501		return(g_sizes);
4502	}
4503	
4504	
4505	/**
4506	 * return if vertical orientation or not
4507	 */
4508	this.isVertical = function(){
4509		return(g_isVertical);
4510	}
4511	
4512	
4513	/**
4514	 * return if the strip is placed or not
4515	 */
4516	this.isPlaced = function(){
4517		
4518		return(g_temp.is_placed);
4519	}
4520	
4521	/**
4522	 * return if the strip moving enabled or not
4523	 */
4524	this.isMoveEnabled = function(){
4525		var isEnabled = isStripMovingEnabled();
4526		return(isEnabled);
4527	}
4528
4529}
4530
4531
4532/**
4533 * touch thumbs control class
4534 * addon to strip gallery
4535 */
4536function UGTouchThumbsControl(){
4537	
4538	var g_parent, g_gallery, g_objGallery, g_objects;
4539	var g_objStrip, g_objStripInner, g_options, g_isVertical;
4540	var g_functions = new UGFunctions();
4541	
4542	//service variables	
4543	var g_serviceParams = {			
4544		touch_portion_time:200,					//the time in ms that the potion is counts for continue touch movement
4545		thumb_touch_slowFactor:0,				//set from user
4546		minDeltaTime: 70,						//don't alow portion less then the minTime
4547		minPath: 10,							//if less then this path, dont' continue motion
4548		limitsBreakAddition: 30,				//the limits break addition for second return animation
4549		returnAnimateSpeed: 500,				//the speed of return animation
4550		animationEasing: "easeOutCubic",		//animation easing function
4551		returnAnimationEasing: "easeOutCubic"	//return animation easing function
4552	};
4553	
4554	
4555	var g_temp = {					//temp variables
4556		touch_active:false,
4557		loop_active:false,
4558		mousePos:0,
4559		innerPos:0,
4560		startPos:0,
4561		startTime:0,		
4562		lastTime:0,
4563		buttonReleaseTime:0,
4564		lastPos:0,
4565		lastPortionPos:0,
4566		lastDeltaTime:0,
4567		lastDeltaPos:0,
4568		speed:0,
4569		handle:"",
4570		touchEnabled: false, 
4571		isControlEnabled: true
4572	};
4573
4574
4575	/**
4576	 * enable the control
4577	 */
4578	this.enable = function(){
4579		g_temp.isControlEnabled = true;
4580	}
4581	
4582	
4583	/**
4584	 * disable the control
4585	 */
4586	this.disable = function(){
4587		g_temp.isControlEnabled = false;		
4588	}
4589	
4590	/**
4591	 * init function for avia controls
4592	 */
4593	this.init = function(objStrip){
4594		
4595		g_parent = objStrip;
4596		g_objects = objStrip.getObjects();
4597		
4598		g_gallery = g_objects.g_gallery;
4599		g_objGallery = g_objects.g_objGallery;	//jquery object
4600				
4601		g_objStrip = g_objects.g_objStrip;
4602		g_objStripInner = g_objects.g_objStripInner;
4603		g_options = g_objects.g_options;
4604		g_isVertical = g_objects.isVertical;
4605		
4606		setServiceParams();
4607		
4608		initEvents();
4609	}
4610	
4611	/**
4612	 * get action related variables
4613	 */
4614	function getActionVars(){
4615		
4616		var currentTime = jQuery.now();
4617
4618		var obj = {};
4619		obj.passedTime = g_temp.lastTime - g_temp.startTime;
4620		obj.lastActiveTime = currentTime - g_temp.buttonReleaseTime;
4621		obj.passedDistance = g_temp.lastPos - g_temp.startPos;
4622		obj.passedDistanceAbs = Math.abs(obj.passedDistance);
4623				
4624		return(obj);
4625	}
4626	
4627	/**
4628	 * return if passed some significant movement
4629	 */
4630	this.isSignificantPassed = function(){
4631		var objVars = getActionVars();
4632		if(objVars.passedTime > 300)
4633			return(true);
4634		
4635		if(objVars.passedDistanceAbs > 30)
4636			return(true);
4637		
4638		return(false);		
4639	}
4640	
4641	
4642	/**
4643	 * return true if the touch dragging or animate motion is active
4644	 */
4645	this.isTouchActive = function(){
4646		
4647		if(g_temp.touch_active == true)
4648			return(true);
4649			
4650		//check if still animating
4651		if(g_objStripInner.is(":animated") == true)
4652			return(true);
4653		
4654		//check if just ended, the touch active continue for a few moments.
4655		var objVars = getActionVars();
4656		if(objVars.lastActiveTime < 50) 
4657			return(true);
4658				
4659		return(false);
4660	}
4661	
4662	/**
4663	 * set service parameters from user parameters
4664	 */
4665	function setServiceParams(){
4666				
4667		//set slow factor by sensetivity of touch motion		
4668		g_serviceParams.thumb_touch_slowFactor = g_functions.normalizeSetting(0.00005, 0.01, 1, 100, g_options.strip_thumb_touch_sensetivity, true);
4669				
4670		//debugLine("slowfactor "+ g_serviceParams.thumb_touch_slowFactor);
4671	}
4672	
4673	
4674	/**
4675	 * get mouse position based on orientation
4676	 */
4677	function getMouseOrientPosition(event){
4678		
4679		if(g_isVertical == false)
4680			return(g_functions.getMousePosition(event).pageX);
4681		else
4682			return(g_functions.getMousePosition(event).pageY);			
4683	}
4684	
4685	/**
4686	 * position the strip according the touch drag diff
4687	 */
4688	function handleStripDrag(mousePos){
4689		var diff = g_temp.mousePos - mousePos;
4690		var distPos = g_temp.innerPos - diff;
4691		
4692		//make harder to drag the limits
4693		var objLimits = g_parent.getInnerStripLimits();
4694		
4695		if(distPos > objLimits.maxPos){
4696			var path = distPos - objLimits.maxPos;
4697			distPos = objLimits.maxPos + path/3;			
4698		}
4699		
4700		if(distPos < objLimits.minPos){
4701			var path = objLimits.minPos - distPos;
4702			distPos = objLimits.minPos - path/3;						
4703		}
4704		
4705		g_parent.positionInnerStrip(distPos);
4706	}
4707	
4708	
4709	/**
4710	 * store initial touch values
4711	 */
4712	function storeInitTouchValues(pagePos){
4713		var currentInnerPos = g_parent.getInnerStripPos();
4714		
4715		//remember current mouse position and inner strip position
4716		g_temp.mousePos = pagePos;
4717		g_temp.innerPos = currentInnerPos;
4718		g_temp.lastPortionPos = currentInnerPos;
4719		g_temp.lastDeltaTime = 0;
4720		g_temp.lastDeltaPos = 0;
4721		
4722		//init position and time related variables
4723		g_temp.startTime = jQuery.now();
4724		g_temp.startPos = g_temp.innerPos;
4725		
4726		g_temp.lastTime = g_temp.startTime;
4727		g_temp.lastPos = g_temp.startPos;
4728		g_temp.speed = 0;
4729	}
4730	
4731	
4732	/**
4733	 * store touch portion data
4734	 */
4735	function storeTouchPortionData(){
4736				
4737		//calc speed
4738		var currentTime = jQuery.now();
4739		var deltaTime = currentTime - g_temp.lastTime;
4740		
4741		if(deltaTime >= g_serviceParams.touch_portion_time){
4742			g_temp.lastDeltaTime = currentTime - g_temp.lastTime;
4743			if(g_temp.lastDeltaTime > g_serviceParams.touch_portion_time)
4744				g_temp.lastDeltaTime = g_serviceParams.touch_portion_time;
4745				
4746			g_temp.lastDeltaPos = g_temp.lastPos - g_temp.lastPortionPos;
4747						
4748			g_temp.lastPortionPos = g_temp.lastPos;
4749			g_temp.lastTime = currentTime;
4750			
4751		}
4752		
4753	}
4754	
4755	
4756	/**
4757	 * continue touch motion - touch motion ending.
4758	 */
4759	function continueTouchMotion(){
4760				
4761		var slowFactor = g_serviceParams.thumb_touch_slowFactor;
4762		
4763		//don't alow portion less then the minTime
4764		var minDeltaTime = g_serviceParams.minDeltaTime;
4765		
4766		//if less then this path, dont' continue motion
4767		var minPath = g_serviceParams.minPath;	
4768		
4769		var currentInnerPos = g_parent.getInnerStripPos();
4770		
4771		var currentTime = jQuery.now();
4772		var deltaTime = currentTime - g_temp.lastTime;
4773		var deltaPos = currentInnerPos - g_temp.lastPortionPos;
4774		
4775		//if time too fast, take last portion values
4776		if(deltaTime < minDeltaTime && g_temp.lastDeltaTime > 0){
4777			deltaTime = g_temp.lastDeltaTime;
4778			deltaPos = g_temp.lastDeltaPos + deltaPos;
4779		}
4780		
4781		//fix delta time
4782		if(deltaTime < minDeltaTime)
4783			deltaTime = minDeltaTime;
4784					
4785		var dir = (deltaPos > 0)?1:-1;
4786		
4787		var speed = 0;
4788		if(deltaTime > 0)
4789			speed = deltaPos / deltaTime;	
4790		
4791		var path = (speed * speed) / (slowFactor * 2) * dir;
4792		
4793		//disable path for very slow motions
4794		if(Math.abs(path) <= minPath)
4795			path = 0;
4796		
4797		
4798		var innerStripPos = g_parent.getInnerStripPos();
4799		var newPos = innerStripPos + path;	
4800		
4801		var correctPos = g_parent.fixInnerStripLimits(newPos);
4802		var objLimits = g_parent.getInnerStripLimits();
4803		
4804		//check the off the limits and return (second animation)
4805		var limitsBreakAddition = g_serviceParams.limitsBreakAddition;
4806		var doQueue = false;
4807		var returnPos = correctPos;
4808		
4809		//fix the first animation position (off the limits)
4810		if(newPos > objLimits.maxPos){
4811			doQueue = true;
4812			correctPos = limitsBreakAddition;
4813			if(newPos < limitsBreakAddition)
4814				correctPos = newPos;			
4815		}
4816				
4817		if(newPos < objLimits.minPos){
4818			doQueue = true;
4819			var maxStopPos = objLimits.minPos - limitsBreakAddition;
4820			correctPos = maxStopPos;
4821			if(newPos > maxStopPos)
4822				correctPos = newPos;
4823		}
4824				
4825		var correctPath = correctPos - innerStripPos;
4826		
4827		//set animation speed		
4828		var animateSpeed =  Math.abs(Math.round(speed / slowFactor));
4829		
4830		//fix animation speed according the paths difference
4831		if(path != 0)
4832			animateSpeed = animateSpeed * correctPath / path;		
4833		
4834		
4835		//Do first animation
4836		if(innerStripPos != correctPos){
4837			
4838			var animateProps = {"left":correctPos+"px"};
4839			if(g_isVertical == true)
4840				animateProps = {"top":correctPos+"px"};		
4841			
4842			g_objStripInner.animate(animateProps ,{
4843					duration: animateSpeed,
4844					easing: g_serviceParams.animationEasing,
4845					queue: true,
4846					progress:onAnimateProgress 
4847			});
4848						
4849		}
4850		
4851				
4852		//do second animation if off limits
4853		if(doQueue == true){
4854			var returnAnimateSpeed = g_serviceParams.returnAnimateSpeed;
4855			
4856			var returnAnimateProps = {"left":returnPos+"px"};
4857			if(g_isVertical == true)
4858				returnAnimateProps = {"top":returnPos+"px"};		
4859			
4860			
4861			g_objStripInner.animate(returnAnimateProps,{				
4862				duration: returnAnimateSpeed,
4863				easing: g_serviceParams.returnAnimationEasing,
4864				queue: true,
4865				progress:onAnimateProgress 
4866			});
4867		}
4868		
4869	}
4870	
4871	/**
4872	 * on animate progress event. store position and trigger event to gallery
4873	 */
4874	function onAnimateProgress(){
4875		g_temp.lastPos = g_parent.getInnerStripPos();
4876		g_parent.triggerStripMoveEvent();
4877	}
4878	
4879	/**
4880	 * start loop while touching strip
4881	 */
4882	function startStripTouchLoop(){
4883		
4884		if(g_temp.loop_active == true)
4885			return(true);
4886			
4887		g_temp.loop_active = true;
4888		g_temp.handle = setInterval(storeTouchPortionData,10);
4889	}
4890	
4891	
4892	/**
4893	 * end loop when not touching
4894	 */
4895	function endStripTouchLoop(event){
4896		
4897		if(g_temp.loop_active == false)
4898			return(true);
4899		
4900		if(event){
4901			var pagePos = getMouseOrientPosition(event);
4902			continueTouchMotion(pagePos);
4903		}
4904		
4905		g_temp.loop_active = false;
4906		g_temp.handle = clearInterval(g_temp.handle);
4907	}
4908	
4909	
4910	/**
4911	 * on tuch end event
4912	 */
4913	function onTouchEnd(event){
4914		
4915		if(g_temp.isControlEnabled == false)
4916			return(true);
4917				
4918		g_temp.buttonReleaseTime = jQuery.now();
4919		
4920		if(g_temp.touch_active == false){
4921			endStripTouchLoop(event);
4922			return(true);
4923		}
4924		
4925		event.preventDefault();
4926			
4927		g_temp.touch_active = false;
4928		
4929		endStripTouchLoop(event);
4930		
4931		g_objStrip.removeClass("ug-dragging");
4932		
4933	}
4934	
4935	
4936	/**
4937	 * on touch start - start the motion
4938	 * @param event
4939	 */
4940	function onTouchStart(event){
4941		
4942		if(g_temp.isControlEnabled == false)
4943			return(true);
4944		
4945		event.preventDefault();
4946		
4947		g_temp.touch_active = true;		//don't move this up
4948		
4949		var pagePos = getMouseOrientPosition(event);
4950					
4951		//stop inner animation if exist
4952		g_objStripInner.stop(true);
4953		
4954		//store initial touch values
4955		storeInitTouchValues(pagePos);
4956		startStripTouchLoop();
4957		
4958		g_objStrip.addClass("ug-dragging");
4959	}
4960	
4961	
4962	/**
4963	 * on touch move event, move the strip
4964	 */
4965	function onTouchMove(event){
4966		
4967		if(g_temp.isControlEnabled == false)
4968			return(true);		
4969		
4970		if(g_temp.touch_active == false)
4971			return(true);
4972		
4973		event.preventDefault();
4974		
4975		//detect moving without button press
4976		if(event.buttons == 0){
4977			g_temp.touch_active = false;
4978			
4979			endStripTouchLoop(event);
4980			return(true);
4981		}
4982	
4983		//store current position
4984		var pagePos = getMouseOrientPosition(event);
4985		g_temp.lastPos = g_parent.getInnerStripPos();
4986		
4987		handleStripDrag(pagePos);
4988		
4989		storeTouchPortionData();
4990		
4991	}
4992	
4993	
4994	/**
4995	 * init strip touch events
4996	 */
4997	function initEvents(){
4998		
4999		//strip mouse down - drag start
5000		g_objStrip.bind("mousedown touchstart",onTouchStart);
5001
5002		
5003		//on body mouse up - drag end
5004		jQuery(window).add("body").bind("mouseup touchend",onTouchEnd);
5005				
5006		//on body move
5007		jQuery("body").bind("mousemove touchmove", onTouchMove);
5008		
5009	}
5010	
5011	
5012	/**
5013	 * destroy the touch events
5014	 */
5015	this.destroy = function(){
5016		g_objStrip.unbind("mousedown");
5017		g_objStrip.unbind("touchstart");
5018		jQuery(window).add("body").unbind("mouseup").unbind("touchend");
5019		jQuery("body").unbind("mousemove").unbind("touchmove");
5020	}
5021}
5022
5023
5024/** -------------- Panel Base Functions ---------------------*/
5025
5026function UGPanelsBase(){
5027	
5028	var g_temp, g_panel, g_objPanel, g_options, g_objThis;
5029	var g_gallery = new UniteGalleryMain();
5030	var t = this, g_objHandle, g_objGallery;
5031	var g_functions = new UGFunctions();
5032	
5033	
5034	/**
5035	 * init the base panel
5036	 */
5037	this.init = function(gallery, g_tempArg, g_panelArg, options, g_objThisArg){
5038		g_temp = g_tempArg; 
5039		g_panel = g_panelArg;
5040		g_gallery = gallery;
5041		g_options = options;
5042		g_objThis = g_objThisArg;
5043		
5044		g_objGallery = jQuery(g_gallery);
5045	}
5046
5047	/**
5048	 * set common panels html
5049	 */
5050	this.setHtml = function(g_objPanelArg){
5051		
5052		g_objPanel = g_objPanelArg;
5053		
5054		if(g_temp.panelType == "strip")
5055			var enable_handle = g_options.strippanel_enable_handle;
5056		else
5057			var enable_handle = g_options.gridpanel_enable_handle;
5058		
5059		// add handle
5060		if (enable_handle == true) {
5061			g_objHandle = new UGPanelHandle();
5062			g_objHandle.init(g_panel, g_objPanel, g_options, g_temp.panelType, g_gallery);
5063			g_objHandle.setHtml();
5064		}
5065		
5066		
5067		//set disabled at start if exists
5068		if(g_temp.isDisabledAtStart === true){
5069			var html = "<div class='ug-overlay-disabled'></div>";
5070			g_objPanel.append(html);
5071			
5072			setTimeout(function(){
5073				g_objPanel.children(".ug-overlay-disabled").hide();
5074			}, g_temp.disabledAtStartTimeout);
5075		
5076		}
5077		
5078	}
5079	
5080	
5081	/**
5082	 * place common elements
5083	 */
5084	this.placeElements = function(){
5085		
5086		// place handle
5087		if (g_objHandle)
5088			g_objHandle.placeHandle();		
5089	}
5090	
5091	
5092	/**
5093	 * init common events
5094	 */
5095	this.initEvents = function(){
5096		
5097		// set handle events
5098		if (g_objHandle){
5099			g_objHandle.initEvents();
5100			
5101			//set on slider action events
5102			g_objGallery.on(g_gallery.events.SLIDER_ACTION_START, function(){			
5103				g_objHandle.hideHandle();
5104			});
5105			
5106			g_objGallery.on(g_gallery.events.SLIDER_ACTION_END, function(){			
5107				g_objHandle.showHandle();
5108			});
5109			
5110		}
5111		
5112	}
5113	
5114	/**
5115	 * destroy the panel events
5116	 */
5117	this.destroy = function(){
5118		
5119		if(g_objHandle){
5120			g_objHandle.destroy();
5121			g_objGallery.off(g_gallery.events.SLIDER_ACTION_START);
5122			g_objGallery.off(g_gallery.events.SLIDER_ACTION_END);
5123		}
5124		
5125	}
5126	
5127	/**
5128	 * place panel with some animation
5129	 */
5130	function placePanelAnimation(panelDest, functionOnComplete) {
5131
5132		switch (g_temp.orientation) {
5133		case "right": // vertical
5134		case "left":
5135			var objCss = {
5136				left : panelDest + "px"
5137			};
5138			break;
5139		case "top":
5140		case "bottom":
5141			var objCss = {
5142				top : panelDest + "px"
5143			};
5144			break;
5145		}
5146
5147		g_objPanel.stop(true).animate(objCss, {
5148			duration : 300,
5149			easing : "easeInOutQuad",
5150			queue : false,
5151			complete : function() {
5152				if (functionOnComplete)
5153					functionOnComplete();
5154			}
5155		});
5156
5157	}
5158	
5159	
5160	/**
5161	 * place the panel without animation
5162	 * 
5163	 * @param panelDest
5164	 */
5165	function placePanelNoAnimation(panelDest) {
5166
5167		switch (g_temp.orientation) {
5168		case "right": // vertical
5169		case "left":
5170			g_functions.placeElement(g_objPanel, panelDest, null);
5171			break;
5172		case "top":
5173		case "bottom":
5174			g_functions.placeElement(g_objPanel, null, panelDest);
5175			break;
5176		}
5177	}
5178	
5179	/**
5180	 * event on panel slide finish
5181	 */
5182	function onPanelSlideFinish() {
5183
5184		g_objThis.trigger(g_panel.events.FINISH_MOVE);
5185
5186	}
5187	
5188	
5189	/**
5190	 * open the panel
5191	 */
5192	this.openPanel = function(noAnimation) {
5193
5194		if (!noAnimation)
5195			var noAnimation = false;
5196
5197		if (g_objPanel.is(":animated"))
5198			return (false);
5199
5200		if (g_temp.isClosed == false)
5201			return (false);
5202
5203		g_temp.isClosed = false;
5204
5205		g_objThis.trigger(g_panel.events.OPEN_PANEL);
5206
5207		if (noAnimation === false)
5208			placePanelAnimation(g_temp.originalPos, onPanelSlideFinish);
5209		else {
5210
5211			placePanelNoAnimation(g_temp.originalPos);
5212			onPanelSlideFinish();
5213		}
5214
5215	}
5216
5217	
5218	/**
5219	 * close the panel (slide in)
5220	 */
5221	this.closePanel = function(noAnimation) {
5222
5223		if (!noAnimation)
5224			var noAnimation = false;
5225
5226		if (g_objPanel.is(":animated"))
5227			return (false);
5228
5229		if (g_temp.isClosed == true)
5230			return (false);
5231
5232		var panelDest = t.getClosedPanelDest();
5233
5234		g_temp.isClosed = true;
5235
5236		g_objThis.trigger(g_panel.events.CLOSE_PANEL);
5237
5238		if (noAnimation === false)
5239			placePanelAnimation(panelDest, onPanelSlideFinish);
5240		else {
5241			placePanelNoAnimation(panelDest);
5242			onPanelSlideFinish();
5243		}
5244
5245	}
5246	
5247	/**
5248	 * set the panel that it's in closed state, and set original pos for opening
5249	 * later
5250	 */
5251	this.setClosedState = function(originalPos) {
5252		
5253		g_temp.originalPos = originalPos;
5254		g_objThis.trigger(g_panel.events.CLOSE_PANEL);
5255
5256		g_temp.isClosed = true;
5257	}
5258
5259	/**
5260	 * set the panel opened state
5261	 */
5262	this.setOpenedState = function(originalPos) {
5263		g_objThis.trigger(g_panel.events.OPEN_PANEL);
5264
5265		g_temp.isClosed = false;
5266	}
5267
5268	/**
5269	 * get closed panel destanation
5270	 */
5271	this.getClosedPanelDest = function() {
5272
5273		var objPanelSize = g_functions.getElementSize(g_objPanel), panelDest;
5274
5275		switch (g_temp.orientation) {
5276		case "left":
5277			g_temp.originalPos = objPanelSize.left;
5278			panelDest = -g_temp.panelWidth;
5279			break;
5280		case "right":
5281			g_temp.originalPos = objPanelSize.left;
5282			var gallerySize = g_gallery.getSize();
5283			panelDest = gallerySize.width;
5284			break;
5285		case "top":
5286			g_temp.originalPos = objPanelSize.top;
5287			panelDest = -g_temp.panelHeight;
5288			break;
5289		case "bottom":
5290			g_temp.originalPos = objPanelSize.top;
5291			var gallerySize = g_gallery.getSize();
5292			panelDest = gallerySize.height;
5293			break;
5294		}
5295
5296		return (panelDest);
5297	}
5298
5299
5300	/**
5301	 * tells if the panel is closed
5302	 */
5303	this.isPanelClosed = function() {
5304
5305		return (g_temp.isClosed);
5306	}
5307	
5308	
5309	/**
5310	 * set the panel disabled at start, called after init before setHtml
5311	 * it's enabled again after timeout end
5312	 */
5313	this.setDisabledAtStart = function(timeout){
5314		
5315		if(timeout <= 0)
5316			return(false);
5317			
5318		g_temp.isDisabledAtStart = true;
5319		g_temp.disabledAtStartTimeout = timeout;
5320		
5321	}
5322	
5323	
5324}
5325
5326
5327/** -------------- Panel Handle object ---------------------*/
5328
5329function UGPanelHandle(){
5330	
5331	var t = this, g_objPanel, g_panel, g_objHandleTip, g_panelOptions = {};
5332	var g_functions = new UGFunctions();
5333	
5334	var g_options = {
5335			panel_handle_align: "top",		//top, middle, bottom , left, right, center - close handle tip align on the handle bar according panel orientation
5336			panel_handle_offset: 0,			//offset of handle bar according the valign
5337			panel_handle_skin: 0			//skin of the handle, if empty inherit from gallery skin
5338	};
5339	
5340	
5341	/**
5342	 * init the handle
5343	 */
5344	this.init = function(panel, objPanel, panelOptions, panelType, gallery){
5345		g_panel = panel;
5346		g_objPanel = objPanel;
5347		
5348		//set needed options
5349		switch(panelType){		
5350			case "grid":
5351				g_options.panel_handle_align = panelOptions.gridpanel_handle_align;
5352				g_options.panel_handle_offset = panelOptions.gridpanel_handle_offset;
5353				g_options.panel_handle_skin = panelOptions.gridpanel_handle_skin;
5354			break;
5355			case "strip":
5356				g_options.panel_handle_align = panelOptions.strippanel_handle_align;
5357				g_options.panel_handle_offset = panelOptions.strippanel_handle_offset;
5358				g_options.panel_handle_skin = panelOptions.strippanel_handle_skin;
5359			break;
5360			default:
5361				throw new Error("Panel handle error: wrong panel type: " + panelType);			
5362			break;
5363		}
5364		
5365		//set arrows skin:
5366		var galleryOptions = gallery.getOptions();
5367		var globalSkin = galleryOptions.gallery_skin;		
5368		if(g_options.panel_handle_skin == "")
5369			g_options.panel_handle_skin = globalSkin;
5370		
5371		
5372	}
5373	
5374	
5375	/**
5376	 * set handle html
5377	 */
5378	this.setHtml = function(){
5379		
5380		var orientation = g_panel.getOrientation();
5381				
5382		var classTip = "ug-panel-handle-tip";
5383		
5384		switch(orientation){
5385			case "right":
5386				classTip += " ug-handle-tip-left";				
5387			break;
5388			case "left":
5389				classTip += " ug-handle-tip-right";
5390			break;
5391			case "bottom":
5392				classTip += " ug-handle-tip-top";				
5393			break;
5394			case "top":
5395				classTip += " ug-handle-tip-bottom";
5396			break;
5397		}
5398		
5399		g_objPanel.append("<div class='"+classTip+" ug-skin-" + g_options.panel_handle_skin + "'></div>");
5400		g_objHandleTip = g_objPanel.children(".ug-panel-handle-tip");
5401	}
5402	
5403	
5404	/**
5405	 * remove hover state of the tip
5406	 */
5407	function removeHoverState(){
5408				
5409		g_objHandleTip.removeClass("ug-button-hover");
5410	}
5411	
5412	/**
5413	 * add closed state class
5414	 */
5415	function setClosedState(){
5416				
5417		g_objHandleTip.addClass("ug-button-closed");		
5418	}
5419	
5420	/**
5421	 * add closed state class
5422	 */
5423	function removeClosedState(){
5424		g_objHandleTip.removeClass("ug-button-closed");		
5425	}
5426
5427	/**
5428	 * on handle click, close or open panel
5429	 */
5430	function onHandleClick(event){
5431		
5432		event.stopPropagation();
5433		event.stopImmediatePropagation();
5434		
5435		if(g_functions.validateClickTouchstartEvent(event.type) == false)
5436			return(true);
5437		
5438		if(g_panel.isPanelClosed())
5439			g_panel.openPanel();
5440		else
5441			g_panel.closePanel();
5442	}
5443	
5444	/**
5445	 * init events
5446	 */
5447	this.initEvents = function(){
5448		g_functions.addClassOnHover(g_objHandleTip);
5449		g_objHandleTip.bind("click touchstart", onHandleClick);
5450		
5451		//on panel open
5452		jQuery(g_panel).on(g_panel.events.OPEN_PANEL, function(){
5453			removeHoverState();
5454			removeClosedState();
5455		});
5456		
5457		//one panel close
5458		jQuery(g_panel).on(g_panel.events.CLOSE_PANEL, function(){
5459			removeHoverState();
5460			setClosedState();
5461		});
5462		
5463	}
5464	
5465	/**
5466	 * destroy the handle panel events
5467	 */
5468	this.destroy = function(){
5469		g_functions.destroyButton(g_objHandleTip);
5470		jQuery(g_panel).off(g_panel.events.OPEN_PANEL);
5471		jQuery(g_panel).off(g_panel.events.CLOSE_PANEL);
5472	}
5473	
5474	
5475	
5476	/**
5477	 * check and fix align option, set write direction
5478	 */
5479	function checkAndFixAlign(){
5480		var orientation = g_panel.getOrientation();
5481		
5482		switch(orientation){
5483			case "right":
5484			case "left":
5485				if(g_options.panel_handle_align != "top" && g_options.panel_handle_align != "bottom")
5486					g_options.panel_handle_align = "top";
5487			break;
5488			case "bottom":
5489				if(g_options.panel_handle_align != "left" && g_options.panel_handle_align != "right")
5490					g_options.panel_handle_align = "left";
5491			break;
5492			case "top":
5493				if(g_options.panel_handle_align != "left" && g_options.panel_handle_align != "right")
5494					g_options.panel_handle_align = "right";				
5495			break;
5496		}		
5497		
5498	}
5499	
5500	
5501	/**
5502	 * place the panel
5503	 */
5504	this.placeHandle = function(){
5505		var handleSize = g_functions.getElementSize(g_objHandleTip);
5506		
5507		checkAndFixAlign();
5508				
5509		var orientation = g_panel.getOrientation();
5510		
5511		switch(orientation){
5512			case "left":
5513				g_functions.placeElement(g_objHandleTip, "right", g_options.panel_handle_align, -handleSize.width);
5514			break;
5515			case "right":
5516				g_functions.placeElement(g_objHandleTip, -handleSize.width, g_options.panel_handle_align, 0 ,g_options.panel_handle_offset);
5517			break;
5518			case "top":
5519				g_functions.placeElement(g_objHandleTip, g_options.panel_handle_align, "bottom", g_options.panel_handle_offset, -handleSize.height);
5520			break;
5521			case "bottom":
5522				g_functions.placeElement(g_objHandleTip, g_options.panel_handle_align, "top", g_options.panel_handle_offset, -handleSize.height);
5523			break;
5524			default:
5525				throw new Error("Wrong panel orientation: " + orientation);
5526			break;
5527		}
5528		
5529	}
5530	
5531	/**
5532	 * hide the handle
5533	 */
5534	this.hideHandle = function(){
5535		
5536		if(g_objHandleTip.is(":visible") == true)
5537			g_objHandleTip.hide();
5538	
5539	}
5540	
5541	/**
5542	 * show the handle
5543	 */
5544	this.showHandle = function(){
5545		
5546		if(g_objHandleTip.is(":visible") == false)
5547			g_objHandleTip.show();
5548		
5549	}
5550	
5551	
5552}
5553
5554/**
5555 * grid panel class addon to grid gallery
5556 */
5557function UGStripPanel() {
5558
5559	var t = this, g_objThis = jQuery(this);
5560	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objWrapper, g_objPanel;
5561	var g_functions = new UGFunctions(), g_objStrip = new UGThumbsStrip(), g_panelBase = new UGPanelsBase();
5562	var g_objButtonNext, g_objButtonPrev;
5563
5564	this.events = {
5565		FINISH_MOVE : "gridpanel_move_finish", // called after close or open panel (slide finish).
5566		OPEN_PANEL : "open_panel", 			   // called before opening the panel.
5567		CLOSE_PANEL : "close_panel" 		   // called before closing the panel.
5568	};
5569
5570	var g_options = {
5571
5572		strippanel_vertical_type : false, // true, false - specify if the panel is vertical or horizonatal type
5573
5574		strippanel_padding_top : 8,       // space from top of the panel
5575		strippanel_padding_bottom : 8,    // space from bottom of the panel
5576
5577		strippanel_padding_left : 0,      // space from left of the panel
5578		strippanel_padding_right : 0,     // space from right of the panel
5579
5580		strippanel_enable_buttons : true, // enable buttons from the sides of the panel
5581		strippanel_buttons_skin : "",     // skin of the buttons, if empty inherit from gallery skin
5582										  
5583		strippanel_padding_buttons : 2,   // padding between the buttons and the panel
5584
5585		strippanel_buttons_role : "scroll_strip",   // scroll_strip, advance_item - the role of the side buttons
5586		
5587		strippanel_enable_handle : true,  // enable grid handle
5588		strippanel_handle_align : "top",  // top, middle, bottom , left, right, center - close handle tip align on the handle bar according panel orientation
5589		strippanel_handle_offset : 0, 	  // offset of handle bar according the valign
5590										
5591		strippanel_handle_skin : "", 	  // skin of the handle, if empty inherit  from gallery skin
5592
5593		strippanel_background_color : ""  // background color of the strip wrapper, if not set, it will be taken from the css
5594		
5595	};
5596
5597	var g_defaults_vertical = {
5598		strip_vertical_type : true,
5599		strippanel_padding_left : 8,
5600		strippanel_padding_right : 8,
5601		strippanel_padding_top : 0,
5602		strippanel_padding_bottom : 0
5603	};
5604
5605	var g_defaults_no_buttons = {
5606		strippanel_padding_left : 8,
5607		strippanel_padding_right : 8,
5608		strippanel_padding_top : 8,
5609		strippanel_padding_bottom : 8
5610	};
5611
5612	var g_temp = {
5613		panelType: "strip",
5614		panelWidth : 0,
5615		panelHeight : 0,
5616		isEventsInited : false,
5617		isClosed : false,
5618		orientation : null,
5619		originalPos : null,
5620		isFirstRun : true
5621	};
5622
5623	/**
5624	 * init the panel
5625	 */
5626	function initPanel(gallery, customOptions) {
5627		g_gallery = gallery;
5628
5629		g_objGallery = jQuery(g_gallery);
5630
5631		g_options = jQuery.extend(g_options, customOptions);
5632
5633		var repeatCustomOptions = false;
5634
5635		if (g_options.strippanel_vertical_type == true) {
5636			g_options = jQuery.extend(g_options, g_defaults_vertical);
5637			repeatCustomOptions = true;
5638		}
5639
5640		if (g_options.strippanel_enable_buttons == false) {
5641			g_options = jQuery.extend(g_options, g_defaults_no_buttons);
5642			repeatCustomOptions = true;
5643		}
5644
5645		if (repeatCustomOptions == true)
5646			g_options = jQuery.extend(g_options, customOptions); // do the
5647		
5648		
5649		// set arrows skin:
5650		var galleryOptions = g_gallery.getOptions();
5651		var globalSkin = galleryOptions.gallery_skin;
5652		if (g_options.strippanel_buttons_skin == "")
5653			g_options.strippanel_buttons_skin = globalSkin;
5654
5655		g_objWrapper = g_gallery.getElement();
5656		
5657		//init the base panel object:
5658		g_panelBase.init(g_gallery, g_temp, t, g_options, g_objThis);
5659		
5660		//init thumbs strip
5661		g_objStrip = new UGThumbsStrip();
5662		g_objStrip.init(g_gallery, g_options);
5663		
5664	}
5665
5666	
5667	/**
5668	 * validate panel before run
5669	 */
5670	function validatePanelBeforeRun() {
5671		
5672		if (g_options.strippanel_vertical_type == false) { // horizontal
5673															// validate
5674			if (g_temp.panelWidth == 0) {
5675				throw new Error(
5676						"Strip panel error: The width not set, please set width");
5677				return (false);
5678			}
5679
5680		} else { // vertical validate
5681
5682			if (g_temp.panelHeight == 0) {
5683				throw new Error(
5684						"Strip panel error: The height not set, please set height");
5685				return (false);
5686			}
5687
5688		}
5689
5690		// validate orientation
5691		if (g_temp.orientation == null) {
5692			throw new Error(
5693					"Wrong orientation, please set panel orientation before run");
5694			return (false);
5695		}
5696
5697		return (true);
5698	}
5699
5700	/**
5701	 * run the panel
5702	 */
5703	function runPanel() {
5704
5705		// validation
5706		if (g_temp.isFirstRun == true && validatePanelBeforeRun() == false)
5707			return (false);
5708
5709		g_objStrip.run();
5710		
5711		setElementsSize();
5712		placeElements();
5713				
5714		initEvents();
5715
5716		g_temp.isFirstRun = false;
5717
5718		checkSideButtons();
5719	}
5720
5721	/**
5722	 * set panel html
5723	 */
5724	function setPanelHtml(parentContainer) {
5725		
5726		if (!parentContainer)
5727			var parentContainer = g_objWrapper;
5728
5729		// add panel wrapper
5730		parentContainer.append("<div class='ug-strip-panel'></div>");
5731
5732		g_objPanel = parentContainer.children('.ug-strip-panel');
5733
5734		// add arrows:
5735		if (g_options.strippanel_enable_buttons == true) {
5736
5737			var arrowPrevClass = "ug-strip-arrow-left";
5738			var arrowNextClass = "ug-strip-arrow-right";
5739			if (g_options.strippanel_vertical_type == true) {
5740				arrowPrevClass = "ug-strip-arrow-up";
5741				arrowNextClass = "ug-strip-arrow-down";
5742			}
5743
5744			g_objPanel.append("<div class='ug-strip-arrow " + arrowPrevClass
5745					+ " ug-skin-" + g_options.strippanel_buttons_skin
5746					+ "'><div class='ug-strip-arrow-tip'></div></div>");
5747			g_objPanel.append("<div class='ug-strip-arrow " + arrowNextClass
5748					+ " ug-skin-" + g_options.strippanel_buttons_skin
5749					+ "'><div class='ug-strip-arrow-tip'></div></div>");
5750
5751		}
5752		
5753		g_panelBase.setHtml(g_objPanel);
5754		
5755		g_objStrip.setHtml(g_objPanel);
5756		
5757		if (g_options.strippanel_enable_buttons == true) {
5758			g_objButtonPrev = g_objPanel.children("." + arrowPrevClass);
5759			g_objButtonNext = g_objPanel.children("." + arrowNextClass);
5760		}
5761
5762		setHtmlProperties();
5763	}
5764
5765	/**
5766	 * set html properties according the options
5767	 */
5768	function setHtmlProperties() {
5769
5770		// set panel background color
5771		if (g_options.strippanel_background_color != "")
5772			g_objPanel.css("background-color",
5773					g_options.strippanel_background_color);
5774
5775	}
5776
5777	/**
5778	 * set elements size horizontal type
5779	 */
5780	function setElementsSize_hor() {
5781		
5782		// get strip height
5783		var stripHeight = g_objStrip.getHeight();
5784		var panelWidth = g_temp.panelWidth;
5785
5786		// set buttons height
5787		if (g_objButtonNext) {
5788			g_objButtonPrev.height(stripHeight);
5789			g_objButtonNext.height(stripHeight);
5790
5791			// arrange buttons tip
5792			var prevTip = g_objButtonPrev.children(".ug-strip-arrow-tip");
5793			g_functions.placeElement(prevTip, "center", "middle");
5794
5795			var nextTip = g_objButtonNext.children(".ug-strip-arrow-tip");
5796			g_functions.placeElement(nextTip, "center", "middle");
5797		}
5798
5799		// set panel height
5800		var panelHeight = stripHeight + g_options.strippanel_padding_top
5801				+ g_options.strippanel_padding_bottom;
5802
5803		// set panel size
5804		g_objPanel.width(panelWidth);
5805		g_objPanel.height(panelHeight);
5806
5807		g_temp.panelHeight = panelHeight;
5808
5809		// set strip size
5810		var stripWidth = panelWidth - g_options.strippanel_padding_left	- g_options.strippanel_padding_right;
5811
5812		if (g_objButtonNext) {
5813			var buttonWidth = g_objButtonNext.outerWidth();
5814			stripWidth = stripWidth - buttonWidth * 2 - g_options.strippanel_padding_buttons * 2;
5815		}
5816
5817		g_objStrip.resize(stripWidth);
5818	}
5819
5820	/**
5821	 * set elements size vertical type
5822	 */
5823	function setElementsSize_vert() {
5824				
5825		// get strip width
5826		var stripWidth = g_objStrip.getWidth();
5827		var panelHeight = g_temp.panelHeight;
5828		
5829		// set buttons height
5830		if (g_objButtonNext) {
5831			g_objButtonPrev.width(stripWidth);
5832			g_objButtonNext.width(stripWidth);
5833
5834			// arrange buttons tip
5835			var prevTip = g_objButtonPrev.children(".ug-strip-arrow-tip");
5836			g_functions.placeElement(prevTip, "center", "middle");
5837
5838			var nextTip = g_objButtonNext.children(".ug-strip-arrow-tip");
5839			g_functions.placeElement(nextTip, "center", "middle");
5840		}
5841
5842		// set panel width
5843		var panelWidth = stripWidth + g_options.strippanel_padding_left
5844				+ g_options.strippanel_padding_right;
5845
5846		// set panel size
5847		g_objPanel.width(panelWidth);
5848		g_objPanel.height(panelHeight);
5849
5850		g_temp.panelWidth = panelWidth;
5851
5852		// set strip size
5853		var stripHeight = panelHeight - g_options.strippanel_padding_top
5854				- g_options.strippanel_padding_bottom;
5855
5856		if (g_objButtonNext) {
5857			var buttonHeight = g_objButtonNext.outerHeight();
5858			stripHeight = stripHeight - buttonHeight * 2
5859					- g_options.strippanel_padding_buttons * 2;
5860		}
5861
5862		g_objStrip.resize(stripHeight);
5863	}
5864
5865	/**
5866	 * set elements size and place the elements
5867	 */
5868	function setElementsSize() {
5869
5870		if (g_options.strippanel_vertical_type == false)
5871			setElementsSize_hor();
5872		else
5873			setElementsSize_vert();
5874	}
5875
5876	/**
5877	 * place elements horizontally
5878	 */
5879	function placeElements_hor() {
5880
5881		// place buttons
5882		if (g_objButtonNext) {
5883			g_functions.placeElement(g_objButtonPrev, "left", "top",
5884					g_options.strippanel_padding_left,
5885					g_options.strippanel_padding_top);
5886			g_functions.placeElement(g_objButtonNext, "right", "top",
5887					g_options.strippanel_padding_right,
5888					g_options.strippanel_padding_top);
5889		}
5890
5891		var stripX = g_options.strippanel_padding_left;
5892		if (g_objButtonNext)
5893			stripX += g_objButtonNext.outerWidth()
5894					+ g_options.strippanel_padding_buttons;
5895
5896		g_objStrip.setPosition(stripX, g_options.strippanel_padding_top);
5897
5898	}
5899
5900	/**
5901	 * place elements vertically
5902	 */
5903	function placeElements_vert() {
5904
5905		// place buttons
5906		if (g_objButtonNext) {
5907			g_functions.placeElement(g_objButtonPrev, "left", "top",
5908					g_options.strippanel_padding_left,
5909					g_options.strippanel_padding_top);
5910			g_functions.placeElement(g_objButtonNext, "left", "bottom",
5911					g_options.strippanel_padding_left,
5912					g_options.strippanel_padding_bottom);
5913		}
5914
5915		var stripY = g_options.strippanel_padding_top;
5916		if (g_objButtonNext)
5917			stripY += g_objButtonNext.outerHeight()
5918					+ g_options.strippanel_padding_buttons;
5919
5920		g_objStrip.setPosition(g_options.strippanel_padding_left, stripY);
5921	}
5922
5923	/**
5924	 * place elements
5925	 */
5926	function placeElements() {
5927
5928		if (g_options.strippanel_vertical_type == false)
5929			placeElements_hor();
5930		else
5931			placeElements_vert();
5932
5933		g_panelBase.placeElements();
5934
5935	}
5936
5937
5938
5939	function __________EVENTS___________() {
5940	}
5941	;
5942
5943	/**
5944	 * on next button click
5945	 */
5946	function onNextButtonClick(objButton) {
5947
5948		if (g_functions.isButtonDisabled(objButton))
5949			return (true);
5950
5951		if (g_options.strippanel_buttons_role == "advance_item")
5952			g_gallery.nextItem();
5953		else
5954			g_objStrip.scrollForeward();
5955	}
5956
5957	/**
5958	 * on previous button click
5959	 */
5960	function onPrevButtonClick(objButton) {
5961
5962		if (g_functions.isButtonDisabled(objButton))
5963			return (true);
5964
5965		if (g_options.strippanel_buttons_role == "advance_item")
5966			g_gallery.prevItem();
5967		else
5968			g_objStrip.scrollBack();
5969	}
5970
5971	/**
5972	 * check buttons if they need to be disabled or not
5973	 */
5974	function checkSideButtons() {
5975				
5976		if (!g_objButtonNext)
5977			return (true);
5978
5979		// if the strip not movable - disable both buttons
5980		if (g_objStrip.isMoveEnabled() == false) {
5981			g_functions.disableButton(g_objButtonPrev);
5982			g_functions.disableButton(g_objButtonNext);
5983			return (true);
5984		}
5985		
5986		// check the limits
5987		var limits = g_objStrip.getInnerStripLimits();
5988		var pos = g_objStrip.getInnerStripPos();
5989		
5990		if (pos >= limits.maxPos) {
5991			g_functions.disableButton(g_objButtonPrev);
5992		} else {
5993			g_functions.enableButton(g_objButtonPrev);
5994		}
5995
5996		if (pos <= limits.minPos)
5997			g_functions.disableButton(g_objButtonNext);
5998		else
5999			g_functions.enableButton(g_objButtonNext);
6000
6001	}
6002
6003	/**
6004	 * on strip move event
6005	 */
6006	function onStripMove() {
6007		checkSideButtons();
6008	}
6009
6010	/**
6011	 * on item change event, disable or enable buttons according the images
6012	 * position
6013	 */
6014	function onItemChange() {
6015
6016		if (g_gallery.isLastItem())
6017			g_functions.disableButton(g_objButtonNext);
6018		else
6019			g_functions.enableButton(g_objButtonNext);
6020
6021		if (g_gallery.isFirstItem())
6022			g_functions.disableButton(g_objButtonPrev);
6023		else
6024			g_functions.enableButton(g_objButtonPrev);
6025
6026	}
6027
6028
6029	/**
6030	 * init panel events
6031	 */
6032	function initEvents() {
6033
6034		if (g_temp.isEventsInited == true)
6035			return (false);
6036		
6037		g_temp.isEventsInited = true;
6038		
6039		// buttons events
6040		if (g_objButtonNext) {
6041
6042			// add hove class
6043			g_functions.addClassOnHover(g_objButtonNext, "ug-button-hover");
6044			g_functions.addClassOnHover(g_objButtonPrev, "ug-button-hover");
6045
6046			// add click events
6047			g_functions.setButtonOnClick(g_objButtonPrev, onPrevButtonClick);
6048			g_functions.setButtonOnClick(g_objButtonNext, onNextButtonClick);
6049
6050			// add disable / enable buttons on strip move event
6051			if (g_options.strippanel_buttons_role != "advance_item") {
6052				
6053				jQuery(g_objStrip).on(g_objStrip.events.STRIP_MOVE, onStripMove);
6054				
6055				jQuery(g_objStrip).on(g_objStrip.events.INNER_SIZE_CHANGE, checkSideButtons);
6056				
6057				g_objGallery.on(g_gallery.events.SIZE_CHANGE, checkSideButtons);
6058				
6059			} else {
6060				var galleryOptions = g_gallery.getOptions();
6061				if (galleryOptions.gallery_carousel == false)
6062					jQuery(g_gallery).on(g_gallery.events.ITEM_CHANGE, onItemChange);
6063			}
6064
6065		}
6066
6067		g_panelBase.initEvents();
6068	}
6069	
6070	/**
6071	 * destroy the strip panel events
6072	 */
6073	this.destroy = function(){
6074		
6075		if(g_objButtonNext){
6076			g_functions.destroyButton(g_objButtonNext);
6077			g_functions.destroyButton(g_objButtonPrev);
6078			jQuery(g_objStrip).off(g_objStrip.events.STRIP_MOVE);
6079			jQuery(g_gallery).off(g_gallery.events.ITEM_CHANGE);
6080			jQuery(g_gallery).off(g_gallery.events.SIZE_CHANGE);
6081		}
6082		
6083		g_panelBase.destroy();
6084		g_objStrip.destroy();
6085	}
6086	
6087	
6088	/**
6089	 * get panel orientation
6090	 */
6091	this.getOrientation = function() {
6092
6093		return (g_temp.orientation);
6094	}
6095
6096	/**
6097	 * set panel orientation (left, right, top, bottom)
6098	 */
6099	this.setOrientation = function(orientation) {
6100
6101		g_temp.orientation = orientation;
6102	}
6103
6104	
6105	/**
6106	 * init the panel
6107	 */
6108	this.init = function(gallery, customOptions) {
6109		initPanel(gallery, customOptions);
6110	}
6111
6112	/**
6113	 * run the panel
6114	 */
6115	this.run = function() {
6116		runPanel();
6117	}
6118
6119	/**
6120	 * place panel html
6121	 */
6122	this.setHtml = function(parentContainer) {
6123		setPanelHtml(parentContainer);
6124	}
6125
6126	/**
6127	 * get the panel element
6128	 */
6129	this.getElement = function() {
6130		return (g_objPanel);
6131	}
6132
6133	/**
6134	 * get panel size object
6135	 */
6136	this.getSize = function() {
6137
6138		var objSize = g_functions.getElementSize(g_objPanel);
6139
6140		return (objSize);
6141	}
6142
6143	/**
6144	 * set panel width (for horizonal type)
6145	 */
6146	this.setWidth = function(width) {
6147
6148		g_temp.panelWidth = width;
6149
6150	}
6151
6152	/**
6153	 * set panel height (for vertical type)
6154	 */
6155	this.setHeight = function(height) {
6156
6157		g_temp.panelHeight = height;
6158
6159	}
6160
6161	/**
6162	 * resize the panel
6163	 */
6164	this.resize = function(newWidth) {
6165		t.setWidth(newWidth);
6166		setElementsSize();
6167		placeElements();
6168	}
6169	
6170	this.__________Functions_From_Base_____ = function() {}
6171	
6172	/**
6173	 * tells if the panel is closed
6174	 */
6175	this.isPanelClosed = function() {		
6176		return (g_panelBase.isPanelClosed());
6177	}
6178
6179	/**
6180	 * get closed panel destanation
6181	 */
6182	this.getClosedPanelDest = function() {
6183		return g_panelBase.getClosedPanelDest();
6184	}	
6185		
6186	/**
6187	 * open the panel
6188	 */	
6189	this.openPanel = function(noAnimation) {
6190		g_panelBase.openPanel(noAnimation);
6191	}
6192	
6193	
6194	/**
6195	 * close the panel (slide in)
6196	 */
6197	this.closePanel = function(noAnimation) {
6198		g_panelBase.closePanel(noAnimation);		
6199	}	
6200	
6201	/**
6202	 * set the panel opened state
6203	 */
6204	this.setOpenedState = function(originalPos) {
6205		g_panelBase.setOpenedState(originalPos);
6206	}
6207
6208	/**
6209	 * set the panel that it's in closed state, and set original pos for opening later
6210	 */
6211	this.setClosedState = function(originalPos) {
6212		g_panelBase.setClosedState(originalPos);	
6213	}
6214	
6215	/**
6216	 * set custom thumbs of the strip
6217	 */
6218	this.setCustomThumbs = function(funcSetHtml){
6219		
6220		g_objStrip.setCustomThumbs(funcSetHtml);
6221	
6222	}
6223	
6224	/**
6225	 * set panel disabled at start
6226	 */
6227	this.setDisabledAtStart = function(timeout){
6228		
6229		g_panelBase.setDisabledAtStart(timeout);
6230		
6231	}
6232	
6233}
6234
6235
6236/**
6237 * grid panel class
6238 * addon to grid gallery
6239 */
6240function UGGridPanel(){
6241	
6242	var t = this, g_objThis = jQuery(this);
6243	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objWrapper, g_objPanel;
6244	var g_functions = new UGFunctions();
6245	var g_objGrid = new UGThumbsGrid();
6246	var g_panelBase = new UGPanelsBase();
6247	var g_objArrowNext, g_objArrowPrev;
6248	
6249	this.events = {
6250		FINISH_MOVE: "gridpanel_move_finish",	//called after close or open panel (slide finish).
6251		OPEN_PANEL: "open_panel",				//called before opening the panel.
6252		CLOSE_PANEL: "close_panel"				//called before closing the panel.
6253	};
6254	
6255	var g_options = {
6256			gridpanel_vertical_scroll: true,			//vertical or horizontal grid scroll and arrows
6257			gridpanel_grid_align: "middle",				//top , middle , bottom, left, center, right - the align of the grid panel in the gallery 
6258			gridpanel_padding_border_top: 10,		    //padding between the top border of the panel
6259			gridpanel_padding_border_bottom: 4,			//padding between the bottom border of the panel
6260			gridpanel_padding_border_left: 10,			//padding between the left border of the panel
6261			gridpanel_padding_border_right: 10,			//padding between the right border of the panel
6262			
6263			gridpanel_arrows_skin: "",					//skin of the arrows, if empty inherit from gallery skin
6264			gridpanel_arrows_align_vert: "middle",		//borders, grid, middle - vertical align of arrows, to the top and bottom botders, to the grid, or in the middle space.
6265			gridpanel_arrows_padding_vert: 4,			//padding between the arrows and the grid, in case of middle align, it will be minimal padding
6266			gridpanel_arrows_align_hor: "center",		//borders, grid, center - horizontal align of arrows, to the left and right botders, to the grid, or in the center space.
6267			gridpanel_arrows_padding_hor: 10,			//in case of horizontal type only, minimal size from the grid in case of "borders" and size from the grid in case of "grid"
6268			
6269			gridpanel_space_between_arrows: 20,			//space between arrows on horizontal grids only
6270			gridpanel_arrows_always_on: false,			//always show arrows even if the grid is one pane only
6271
6272			gridpanel_enable_handle: true,				//enable grid handle			
6273			gridpanel_handle_align: "top",				//top, middle, bottom , left, right, center - close handle tip align on the handle bar according panel orientation
6274			gridpanel_handle_offset: 0,					//offset of handle bar according the valign
6275			gridpanel_handle_skin: "",					//skin of the handle, if empty inherit from gallery skin
6276			
6277			gridpanel_background_color:""				//background color of the grid wrapper, if not set, it will be taken from the css
6278	};
6279	
6280	
6281	//default options for vertical scroll
6282	var g_defaultsVertical = {
6283			gridpanel_grid_align: "middle",			//top , middle , bottom
6284			gridpanel_padding_border_top: 2,		//padding between the top border of the panel
6285			gridpanel_padding_border_bottom: 2		//padding between the bottom border of the panel
6286	};
6287	
6288	//default options for horizontal type panel
6289	var g_defaultsHorType = {
6290			gridpanel_grid_align: "center"			//left, center, right			
6291	};
6292	
6293	var g_temp = {
6294		panelType: "grid",
6295		isHorType: false,
6296		arrowsVisible: false,
6297		panelHeight: 0,
6298		panelWidth: 0,
6299		originalPosX:null,
6300		isEventsInited: false,
6301		isClosed: false,
6302		orientation: null
6303	};
6304	
6305	
6306	/**
6307	 * init the grid panel
6308	 */
6309	function initGridPanel(gallery, customOptions){
6310		
6311		g_gallery = gallery;
6312		
6313		validateOrientation();
6314		
6315		//set defaults and custom options
6316		if(customOptions && customOptions.vertical_scroll){
6317			g_options.gridpanel_vertical_scroll = customOptions.vertical_scroll;			
6318		}
6319		
6320		g_options = jQuery.extend(g_options, customOptions);
6321				
6322		//set defautls for horizontal panel type
6323		if(g_temp.isHorType == true){
6324						
6325			g_options = jQuery.extend(g_options, g_defaultsHorType);
6326			g_options = jQuery.extend(g_options, customOptions);
6327					
6328		}else if(g_options.gridpanel_vertical_scroll == true){
6329
6330			//set defaults for vertical scroll
6331			g_options = jQuery.extend(g_options, g_defaultsVertical);
6332			g_options = jQuery.extend(g_options, customOptions);
6333			g_options.grid_panes_direction = "bottom";		
6334		}
6335		
6336		//set arrows skin:
6337		var galleryOptions = g_gallery.getOptions();
6338		var globalSkin = galleryOptions.gallery_skin;		
6339		if(g_options.gridpanel_arrows_skin == "")
6340			g_options.gridpanel_arrows_skin = globalSkin;
6341		
6342		
6343		//get the gallery wrapper
6344		var objects = gallery.getObjects();
6345		g_objWrapper = objects.g_objWrapper;
6346		
6347		//init the base panel object:
6348		g_panelBase.init(g_gallery, g_temp, t, g_options, g_objThis);		
6349
6350		//init the grid 
6351		g_objGrid = new UGThumbsGrid();
6352		g_objGrid.init(g_gallery, g_options);
6353
6354	}
6355	
6356	
6357	/**
6358	 * validate the orientation if exists
6359	 */
6360	function validateOrientation(){
6361		
6362		if(g_temp.orientation == null)
6363			throw new Error("Wrong orientation, please set panel orientation before run");
6364		
6365	}
6366	
6367	/**
6368	 * run the rid panel
6369	 */
6370	function runPanel(){
6371		
6372		//validate orientation
6373		validateOrientation();
6374		
6375		processOptions();
6376		
6377		g_objGrid.run();
6378		
6379		setArrows();
6380		setPanelSize();
6381		placeElements();
6382		
6383		initEvents();
6384	}
6385	
6386	
6387	/**
6388	 * set html of the grid panel
6389	 */
6390	function setHtmlPanel(){
6391		
6392		//add panel wrapper
6393		g_objWrapper.append("<div class='ug-grid-panel'></div>");
6394		
6395		g_objPanel = g_objWrapper.children('.ug-grid-panel');
6396		
6397		//add arrows:
6398		if(g_temp.isHorType){
6399			
6400			g_objPanel.append("<div class='grid-arrow grid-arrow-left-hortype ug-skin-" + g_options.gridpanel_arrows_skin + "'></div>");
6401			g_objPanel.append("<div class='grid-arrow grid-arrow-right-hortype ug-skin-" + g_options.gridpanel_arrows_skin + "'></div>");
6402			
6403			g_objArrowPrev = g_objPanel.children(".grid-arrow-left-hortype");
6404			g_objArrowNext = g_objPanel.children(".grid-arrow-right-hortype");
6405		}
6406		else if(g_options.gridpanel_vertical_scroll == false){		//horizonatl arrows
6407			g_objPanel.append("<div class='grid-arrow grid-arrow-left ug-skin-" + g_options.gridpanel_arrows_skin + "'></div>");
6408			g_objPanel.append("<div class='grid-arrow grid-arrow-right ug-skin-" + g_options.gridpanel_arrows_skin + "'></div>");
6409			
6410			g_objArrowPrev = g_objPanel.children(".grid-arrow-left");
6411			g_objArrowNext = g_objPanel.children(".grid-arrow-right");
6412			
6413		}else{		//vertical arrows
6414			g_objPanel.append("<div class='grid-arrow grid-arrow-up ug-skin-" + g_options.gridpanel_arrows_skin + "'></div>");
6415			g_objPanel.append("<div class='grid-arrow grid-arrow-down ug-skin-" + g_options.gridpanel_arrows_skin + "'></div>");
6416			
6417			g_objArrowPrev = g_objPanel.children(".grid-arrow-up");
6418			g_objArrowNext = g_objPanel.children(".grid-arrow-down");
6419		}
6420		
6421		g_panelBase.setHtml(g_objPanel);
6422		
6423		//hide the arrows
6424		g_objArrowPrev.fadeTo(0,0);
6425		g_objArrowNext.fadeTo(0,0);
6426		
6427		g_objGrid.setHtml(g_objPanel);
6428		
6429		setHtmlProperties();
6430	}
6431	
6432	
6433	/**
6434	 * set html properties according the options
6435	 */
6436	function setHtmlProperties(){
6437		
6438		//set panel background color
6439		if(g_options.gridpanel_background_color != "")
6440			g_objPanel.css("background-color",g_options.gridpanel_background_color);
6441	}
6442	
6443	
6444	/**
6445	 * process and fix certain options, avoid arrows and validate options
6446	 */
6447	function processOptions(){
6448		
6449		if(g_options.gridpanel_grid_align == "center")
6450			g_options.gridpanel_grid_align = "middle";
6451	}
6452	
6453		
6454	/**
6455	 * place panel with some animation
6456	 */
6457	function placePanelAnimation(panelX, functionOnComplete){
6458						
6459		var objCss  = {left: panelX + "px"};
6460		
6461		g_objPanel.stop(true).animate(objCss ,{
6462			duration: 300,
6463			easing: "easeInOutQuad",
6464			queue: false,
6465			complete: function(){
6466				if(functionOnComplete)
6467					functionOnComplete();
6468			}
6469		});
6470		
6471	}
6472	
6473		
6474	
6475	/**
6476	 * get max height of the grid according the arrows size
6477	 */
6478	function getGridMaxHeight(){
6479		
6480		//check space taken without arrows for one pane grids
6481		var spaceTaken = g_options.gridpanel_padding_border_top + g_options.gridpanel_padding_border_bottom;
6482		var maxGridHeight = g_temp.panelHeight - spaceTaken;
6483		
6484		if(g_options.gridpanel_arrows_always_on == false){
6485			var numPanes = g_objGrid.getNumPanesEstimationByHeight(maxGridHeight);
6486			if(numPanes == 1)
6487				return(maxGridHeight);
6488		}
6489		
6490		//count the size with arrows
6491		var arrowsSize = g_functions.getElementSize(g_objArrowNext);
6492		var arrowsHeight = arrowsSize.height;
6493		
6494		var spaceTaken = arrowsHeight + g_options.gridpanel_arrows_padding_vert;
6495		
6496		if(g_options.gridpanel_vertical_scroll == true)	//in case of 2 arrows multiply by 2
6497			spaceTaken *= 2;
6498				
6499		spaceTaken += g_options.gridpanel_padding_border_top + g_options.gridpanel_padding_border_bottom;
6500		
6501		maxGridHeight = g_temp.panelHeight - spaceTaken;			
6502		
6503		return(maxGridHeight);
6504	}
6505	
6506	
6507	/**
6508	 * get grid maximum width
6509	 */
6510	function getGridMaxWidth(){
6511				
6512		//check space taken without arrows for one pane grids
6513		var spaceTaken = g_options.gridpanel_padding_border_left + g_options.gridpanel_padding_border_right;
6514				
6515		var maxGridWidth = g_temp.panelWidth - spaceTaken;
6516		
6517		if(g_options.gridpanel_arrows_always_on == false){
6518			var numPanes = g_objGrid.getNumPanesEstimationByWidth(maxGridWidth);
6519						
6520			if(numPanes == 1)
6521				return(maxGridWidth);
6522		}
6523		
6524		//count the size with arrows
6525		var arrowsSize = g_functions.getElementSize(g_objArrowNext);
6526		var arrowsWidth = arrowsSize.width;
6527		
6528		spaceTaken += (arrowsWidth + g_options.gridpanel_arrows_padding_hor) * 2;
6529								
6530		maxGridWidth = g_temp.panelWidth - spaceTaken;			
6531		
6532		return(maxGridWidth);
6533	}
6534		
6535	
6536	/**
6537	 * enable / disable arrows according the grid
6538	 */
6539	function setArrows(){
6540		
6541		var showArrows = false;
6542		if(g_options.gridpanel_arrows_always_on == true){
6543			showArrows = true;
6544		}
6545		else{
6546			var numPanes = g_objGrid.getNumPanes();
6547			if(numPanes > 1)
6548				showArrows = true;
6549		}
6550		
6551		if(showArrows == true){		//show arrows
6552			
6553			g_objArrowNext.show().fadeTo(0,1);
6554			g_objArrowPrev.show().fadeTo(0,1);
6555			g_temp.arrowsVisible = true;
6556			
6557		}else{		//hide arrows
6558			
6559			g_objArrowNext.hide();
6560			g_objArrowPrev.hide();
6561			g_temp.arrowsVisible = false;			
6562		
6563		}
6564		
6565	}
6566	
6567	
6568	/**
6569	 * set panel size by the given height and grid width
6570	 */
6571	function setPanelSize(){
6572		var gridSize = g_objGrid.getSize();
6573				
6574		//set panel size
6575		if(g_temp.isHorType == true)
6576			g_temp.panelHeight = gridSize.height + g_options.gridpanel_padding_border_top + g_options.gridpanel_padding_border_bottom;
6577		else
6578			g_temp.panelWidth = gridSize.width + g_options.gridpanel_padding_border_left + g_options.gridpanel_padding_border_right;
6579		
6580		g_functions.setElementSize(g_objPanel, g_temp.panelWidth, g_temp.panelHeight);
6581		
6582	}
6583	
6584	
6585	/**
6586	 * place the panel without animation
6587	 * @param panelDest
6588	 */
6589	function placePanelNoAnimation(panelDest){
6590		
6591		switch(g_temp.orientation){
6592			case "right":		//vertical
6593			case "left":
6594				g_functions.placeElement(g_objPanel, panelDest, null);
6595			break;
6596		}
6597		
6598	}
6599	
6600	
6601	
6602	function __________EVENTS___________(){};
6603	
6604	
6605	
6606	/**
6607	 * event on panel slide finish
6608	 */
6609	function onPanelSlideFinish(){
6610				
6611		g_objThis.trigger(t.events.FINISH_MOVE);
6612			
6613	}
6614	
6615	
6616	/**
6617	 * init panel events
6618	 */
6619	function initEvents(){
6620		
6621		if(g_temp.isEventsInited == true)
6622			return(false);
6623		
6624		g_temp.isEventsInited = true;
6625				
6626		if(g_objArrowPrev){
6627			g_functions.addClassOnHover(g_objArrowPrev);
6628			g_objGrid.attachPrevPaneButton(g_objArrowPrev);			
6629		}
6630		
6631		
6632		if(g_objArrowNext){
6633			g_functions.addClassOnHover(g_objArrowNext);
6634			g_objGrid.attachNextPaneButton(g_objArrowNext);			
6635		}
6636		
6637		g_panelBase.initEvents();
6638		
6639	}
6640	
6641	
6642	/**
6643	 * destroy the events
6644	 */
6645	this.destroy = function(){
6646		
6647		if(g_objArrowPrev)
6648			g_functions.destroyButton(g_objArrowPrev);
6649		
6650		if(g_objArrowNext)
6651			g_functions.destroyButton(g_objArrowNext);
6652		
6653		g_panelBase.destroy();
6654		
6655		g_objGrid.destroy();
6656	}
6657	
6658	
6659	function ______PLACE_ELEMENTS___________(){};
6660	
6661	
6662	/**
6663	 * get padding left of the grid
6664	 */
6665	function getGridPaddingLeft(){
6666		
6667		var gridPanelLeft = g_options.gridpanel_padding_border_left;
6668		
6669		return(gridPanelLeft);
6670	}
6671	
6672	
6673	/**
6674	 * place elements vertical - grid only
6675	 */
6676	function placeElements_noarrows(){
6677		
6678		//place grid
6679		var gridY = g_options.gridpanel_grid_align, gridPaddingY = 0;
6680		
6681		switch(gridY){
6682			case "top":
6683				gridPaddingY = g_options.gridpanel_padding_border_top;
6684				
6685			break;
6686			case "bottom":
6687				gridPaddingY = g_options.gridpanel_padding_border_bottom;				
6688			break;
6689		}
6690		
6691		var gridPanelLeft = getGridPaddingLeft();
6692		
6693		var gridElement = g_objGrid.getElement();		
6694		g_functions.placeElement(gridElement, gridPanelLeft, gridY, 0 , gridPaddingY);
6695				
6696	}
6697	
6698	
6699	/**
6700	 * place elements vertical - with arrows
6701	 */
6702	function placeElementsVert_arrows(){
6703		
6704		//place grid
6705		var gridY, prevArrowY, nextArrowY, nextArrowPaddingY;
6706		var objArrowSize = g_functions.getElementSize(g_objArrowPrev);		
6707		var objGridSize = g_objGrid.getSize();		
6708		
6709		
6710		switch(g_options.gridpanel_grid_align){
6711			default:
6712			case "top":
6713				gridY = g_options.gridpanel_padding_border_top + objArrowSize.height + g_options.gridpanel_arrows_padding_vert;
6714			break;
6715			case "middle":
6716				gridY = "middle";
6717			break;
6718			case "bottom":
6719				gridY = g_temp.panelHeight - objGridSize.height - objArrowSize.height - g_options.gridpanel_padding_border_bottom - g_options.gridpanel_arrows_padding_vert;
6720			break;
6721		}
6722		
6723		//place the grid
6724		var gridPanelLeft = getGridPaddingLeft();
6725		
6726		var gridElement = g_objGrid.getElement();		
6727		g_functions.placeElement(gridElement, gridPanelLeft, gridY);
6728		
6729		var objGridSize = g_objGrid.getSize();		
6730						
6731		//place arrows
6732		switch(g_options.gridpanel_arrows_align_vert){
6733			default:
6734			case "center":
6735			case "middle":
6736				prevArrowY = (objGridSize.top - objArrowSize.height) / 2;
6737				nextArrowY = objGridSize.bottom + (g_temp.panelHeight - objGridSize.bottom - objArrowSize.height) / 2;
6738				nextArrowPaddingY = 0;
6739			break;
6740			case "grid":
6741				prevArrowY = objGridSize.top - objArrowSize.height - g_options.gridpanel_arrows_padding_vert_vert
6742				nextArrowY = objGridSize.bottom + g_options.gridpanel_arrows_padding_vert;
6743				nextArrowPaddingY = 0;
6744			break;
6745			case "border":
6746			case "borders":
6747				prevArrowY = g_options.gridpanel_padding_border_top;				
6748				nextArrowY = "bottom"; 
6749				nextArrowPaddingY = g_options.gridpanel_padding_border_bottom;
6750			break;
6751		}
6752		
6753		g_functions.placeElement(g_objArrowPrev, "center", prevArrowY);
6754						
6755		g_functions.placeElement(g_objArrowNext, "center", nextArrowY, 0, nextArrowPaddingY);
6756	}
6757	
6758	
6759	/**
6760	 * place elements vertical
6761	 */
6762	function placeElementsVert(){
6763		
6764		if(g_temp.arrowsVisible == true)
6765			placeElementsVert_arrows();
6766		else
6767			placeElements_noarrows();
6768	}
6769	
6770	
6771	/**
6772	 * place elements horizontal with arrows
6773	 */
6774	function placeElementsHor_arrows(){
6775		
6776		var arrowsY, prevArrowPadding, arrowsPaddingY, nextArrowPadding;
6777		var objArrowSize = g_functions.getElementSize(g_objArrowPrev);		
6778		var objGridSize = g_objGrid.getSize();
6779		
6780		//place grid
6781		var gridY = g_options.gridpanel_padding_border_top;
6782		
6783		switch(g_options.gridpanel_grid_align){
6784			case "middle":
6785				
6786				switch(g_options.gridpanel_arrows_align_vert){
6787					default:
6788						var elementsHeight = objGridSize.height + g_options.gridpanel_arrows_padding_vert + objArrowSize.height;
6789						gridY = (g_temp.panelHeight - elementsHeight) / 2;
6790					break;
6791					case "border":
6792					case "borders":
6793						var remainHeight = g_temp.panelHeight - objArrowSize.height - g_options.gridpanel_padding_border_bottom;
6794						gridY = (remainHeight - objGridSize.height) / 2;
6795					break;
6796				}
6797								
6798			break;
6799			case "bottom":
6800				var elementsHeight = objGridSize.height + objArrowSize.height + g_options.gridpanel_arrows_padding_vert;
6801				gridY = g_temp.panelHeight - elementsHeight - g_options.gridpanel_padding_border_bottom;
6802			break;
6803		}
6804				
6805		var gridElement = g_objGrid.getElement();		
6806		var gridPanelLeft = getGridPaddingLeft();
6807		
6808		g_functions.placeElement(gridElement, gridPanelLeft, gridY);
6809		
6810		var objGridSize = g_objGrid.getSize();
6811		
6812		switch(g_options.gridpanel_arrows_align_vert){
6813			default:
6814			case "center":
6815			case "middle":
6816				arrowsY = objGridSize.bottom + (g_temp.panelHeight - objGridSize.bottom - objArrowSize.height) / 2;
6817				arrowsPaddingY = 0;								
6818			break;
6819			case "grid":
6820				arrowsY = objGridSize.bottom + g_options.gridpanel_arrows_padding_vert;
6821				arrowsPaddingY = 0;
6822			break;
6823			case "border":
6824			case "borders":
6825				arrowsY = "bottom";
6826				arrowsPaddingY = g_options.gridpanel_padding_border_bottom;
6827			break;
6828		}
6829		
6830		prevArrowPadding = -objArrowSize.width/2 - g_options.gridpanel_space_between_arrows / 2;
6831				
6832		g_functions.placeElement(g_objArrowPrev, "center", arrowsY, prevArrowPadding, arrowsPaddingY);
6833						
6834		//place next arrow
6835		var nextArrowPadding = Math.abs(prevArrowPadding);		//make positive
6836				
6837		g_functions.placeElement(g_objArrowNext, "center", arrowsY, nextArrowPadding, arrowsPaddingY);
6838					
6839	}
6840	
6841	
6842	/**
6843	 * place elements horizonatal
6844	 */
6845	function placeElementsHor(){
6846		
6847		if(g_temp.arrowsVisible == true)
6848			placeElementsHor_arrows();
6849		else
6850			placeElements_noarrows();
6851		
6852	}
6853	
6854	
6855	/**
6856	 * place elements horizontal type with arrows
6857	 */
6858	function placeElementsHorType_arrows(){
6859		
6860		//place grid
6861		var gridX, prevArrowX, nextArrowX, arrowsY;
6862		var objArrowSize = g_functions.getElementSize(g_objArrowPrev);		
6863		var objGridSize = g_objGrid.getSize();
6864		
6865		switch(g_options.gridpanel_grid_align){
6866			default:
6867			case "left":
6868				gridX = g_options.gridpanel_padding_border_left + g_options.gridpanel_arrows_padding_hor + objArrowSize.width;
6869			break;
6870			case "middle":
6871			case "center":
6872				gridX = "center";
6873			break;
6874			case "right":
6875				gridX = g_temp.panelWidth - objGridSize.width - objArrowSize.width - g_options.gridpanel_padding_border_right - g_options.gridpanel_arrows_padding_hor;
6876			break;
6877		}
6878		
6879		//place the grid		
6880		var gridElement = g_objGrid.getElement();
6881		g_functions.placeElement(gridElement, gridX, g_options.gridpanel_padding_border_top);
6882		objGridSize = g_objGrid.getSize();
6883		
6884		//place arrows, count Y
6885		switch(g_options.gridpanel_arrows_align_vert){
6886			default:
6887			case "center":
6888			case "middle":
6889				arrowsY = (objGridSize.height - objArrowSize.height) / 2 + objGridSize.top;
6890			break;
6891			case "top":
6892				arrowsY = g_options.gridpanel_padding_border_top + g_options.gridpanel_arrows_padding_vert;
6893			break;
6894			case "bottom":
6895				arrowsY = g_temp.panelHeight - g_options.gridpanel_padding_border_bottom - g_options.gridpanel_arrows_padding_vert - objArrowSize.height;
6896			break;
6897		}
6898				
6899		//get arrows X
6900		switch(g_options.gridpanel_arrows_align_hor){
6901			default:
6902			case "borders":
6903				prevArrowX = g_options.gridpanel_padding_border_left;
6904				nextArrowX = g_temp.panelWidth - g_options.gridpanel_padding_border_right - objArrowSize.width;
6905			break;
6906			case "grid":
6907				prevArrowX = objGridSize.left - g_options.gridpanel_arrows_padding_hor - objArrowSize.width;
6908				nextArrowX = objGridSize.right + g_options.gridpanel_arrows_padding_hor;
6909			break;
6910			case "center":
6911				prevArrowX = (objGridSize.left - objArrowSize.width) / 2;
6912				nextArrowX = objGridSize.right + (g_temp.panelWidth - objGridSize.right - objArrowSize.width) / 2;
6913			break;
6914		}
6915		
6916		g_functions.placeElement(g_objArrowPrev, prevArrowX, arrowsY);		
6917		g_functions.placeElement(g_objArrowNext, nextArrowX, arrowsY);
6918	}
6919	
6920	
6921	/**
6922	 * place elements horizontal type without arrows
6923	 */
6924	function placeElementHorType_noarrows(){
6925		
6926		var gridX;
6927		var objGridSize = g_objGrid.getSize();
6928		
6929		switch(g_options.gridpanel_grid_align){
6930			default:
6931			case "left":
6932				gridX = g_options.gridpanel_padding_border_left;
6933			break;
6934			case "middle":
6935			case "center":
6936				gridX = "center";
6937			break;
6938			case "right":
6939				gridX = g_temp.panelWidth - objGridSize.width - g_options.gridpanel_padding_border_right;
6940			break;
6941		}
6942		
6943		//place the grid		
6944		var gridElement = g_objGrid.getElement();
6945		g_functions.placeElement(gridElement, gridX, g_options.gridpanel_padding_border_top);
6946	}
6947	
6948	
6949	/**
6950	 * place elements when the grid in horizontal position
6951	 */
6952	function placeElementsHorType(){
6953		
6954		if(g_temp.arrowsVisible == true)
6955			placeElementsHorType_arrows();
6956		else
6957			placeElementHorType_noarrows();
6958		
6959	}
6960	
6961	
6962	/**
6963	 * place the arrows
6964	 */
6965	function placeElements(){
6966		
6967		if(g_temp.isHorType == false){
6968			
6969			if(g_options.gridpanel_vertical_scroll == true)
6970				placeElementsVert();
6971			else
6972				placeElementsHor();
6973			
6974		}else{
6975			placeElementsHorType();
6976		}
6977		
6978		g_panelBase.placeElements();
6979	}
6980	
6981	
6982	/**
6983	 * get panel orientation
6984	 */
6985	this.getOrientation = function(){
6986		
6987		return(g_temp.orientation);
6988	}
6989	
6990	
6991	/**
6992	 * set panel orientation (left, right, top, bottom)
6993	 */
6994	this.setOrientation = function(orientation){
6995		
6996		g_temp.orientation = orientation;
6997		
6998		//set isHorType temp variable for ease of use
6999		switch(orientation){
7000			case "right":
7001			case "left":
7002				g_temp.isHorType = false;
7003			break;
7004			case "top":
7005			case "bottom":
7006				g_temp.isHorType = true;
7007			break;
7008			default:
7009				throw new Error("Wrong grid panel orientation: " + orientation);
7010			break;
7011		}
7012		
7013	}
7014	
7015	/**
7016	 * set panel height
7017	 */
7018	this.setHeight = function(height){
7019		
7020		if(g_temp.isHorType == true)
7021			throw new Error("setHeight is not appliable to this orientatio ("+g_temp.orientation+"). Please use setWidth");		
7022		
7023		g_temp.panelHeight = height;
7024		var gridMaxHeight = getGridMaxHeight();
7025		
7026		g_objGrid.setMaxHeight(gridMaxHeight);
7027	}
7028	
7029	
7030	/**
7031	 * set panel width
7032	 */
7033	this.setWidth = function(width){
7034
7035		if(g_temp.isHorType == false)
7036			throw new Error("setWidth is not appliable to this orientatio ("+g_temp.orientation+"). Please use setHeight");		
7037		
7038		g_temp.panelWidth = width;
7039		
7040		var gridMaxWidth = getGridMaxWidth();
7041				
7042		g_objGrid.setMaxWidth(gridMaxWidth);
7043	}
7044	
7045	
7046	/**
7047	 * init the panel
7048	 */
7049	this.init = function(gallery, customOptions){
7050		
7051		initGridPanel(gallery, customOptions);
7052	}
7053	
7054	/**
7055	 * place panel html
7056	 */
7057	this.setHtml = function(){
7058		setHtmlPanel();
7059	}
7060	
7061	
7062	/**
7063	 * run the panel
7064	 */
7065	this.run = function(){
7066		
7067		runPanel();
7068	}
7069	
7070	
7071	/**
7072	 * get the panel element
7073	 */
7074	this.getElement = function(){
7075		return(g_objPanel);
7076	}
7077	
7078	
7079	/**
7080	 * get panel size object
7081	 */
7082	this.getSize = function(){
7083		
7084		var objSize = g_functions.getElementSize(g_objPanel);
7085		
7086		return(objSize);
7087	}
7088	
7089	this.__________Functions_From_Base_____ = function() {}
7090	
7091	/**
7092	 * tells if the panel is closed
7093	 */
7094	this.isPanelClosed = function() {		
7095		return (g_panelBase.isPanelClosed());
7096	}
7097
7098	/**
7099	 * get closed panel destanation
7100	 */
7101	this.getClosedPanelDest = function() {
7102		return g_panelBase.getClosedPanelDest();
7103	}	
7104		
7105	/**
7106	 * open the panel
7107	 */	
7108	this.openPanel = function(noAnimation) {
7109		g_panelBase.openPanel(noAnimation);
7110	}
7111	
7112	
7113	/**
7114	 * close the panel (slide in)
7115	 */
7116	this.closePanel = function(noAnimation) {
7117		g_panelBase.closePanel(noAnimation);		
7118	}	
7119	
7120	/**
7121	 * set the panel opened state
7122	 */
7123	this.setOpenedState = function(originalPos) {
7124		g_panelBase.setOpenedState(originalPos);
7125	}
7126
7127	/**
7128	 * set the panel that it's in closed state, and set original pos for opening later
7129	 */
7130	this.setClosedState = function(originalPos) {
7131		g_panelBase.setClosedState(originalPos);	
7132	}
7133	
7134	
7135	/**
7136	 * set panel disabled at start
7137	 */
7138	this.setDisabledAtStart = function(timeout){
7139		
7140		g_panelBase.setDisabledAtStart(timeout);
7141		
7142	}
7143	
7144	
7145}
7146
7147/**
7148 * thumbs class
7149 * addon to strip gallery
7150 */
7151function UGThumbsGrid(){
7152
7153	var t = this, g_objThis = jQuery(this);
7154	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objects, g_objWrapper;
7155	var g_functions = new UGFunctions(), g_arrItems, g_objGrid, g_objInner;
7156	var g_thumbs = new UGThumbsGeneral(), g_tilesDesign = new UGTileDesign();
7157	
7158	var g_options = {
7159		grid_panes_direction: "left",				//where panes will move -> left, bottom
7160		grid_num_cols: 2,							//number of grid columns
7161		grid_min_cols: 2,							//minimum number of columns (for horizontal type) - the tile size is dynamic 
7162		grid_num_rows: 2,							//number of grid rows (for horizontal type)
7163		grid_space_between_cols: 10,				//space between columns
7164		grid_space_between_rows: 10,				//space between rows
7165		grid_space_between_mobile: 10,				//space between rows and cols mobile
7166		grid_transition_duration: 300,				//transition of the panes change duration 
7167		grid_transition_easing: "easeInOutQuad",	//transition of the panes change easing function
7168		grid_carousel: false,						//next pane goes to first when last
7169		grid_padding: 0,							//set padding to the grid
7170		grid_vertical_scroll_ondrag: false			//scroll the gallery on vertical drag
7171	};
7172	
7173	this.events = {
7174		PANE_CHANGE: "pane_change"
7175	};
7176	
7177	var g_temp = {
7178			eventSizeChange: "thumb_size_change",
7179			isHorizontal: false,
7180			isMaxHeight:false,		//set if the height that set is max height. In that case need a height correction
7181			isMaxWidth:false,		//set if the height that set is max height. In that case need a height correction
7182			gridHeight: 0,
7183			gridWidth: 0,
7184			innerWidth: 0,
7185			innerHeight:0,
7186			numPanes:0,
7187			arrPanes:0,
7188			numThumbs:0,
7189			currentPane:0,
7190			numThumbsInPane:0,
7191			isNavigationVertical:false,
7192			touchActive: false,
7193			startScrollPos:0,
7194			isFirstTimeRun:true,
7195			isTilesMode: false,
7196			storedEventID: "thumbsgrid",
7197			tileMaxWidth:null,
7198			tileMaxHeight:null,
7199			spaceBetweenCols: null,
7200			spaceBetweenRows: null
7201		};
7202	
7203	
7204	function __________GENERAL_________(){};
7205	
7206	/**
7207	 * init the gallery
7208	 */
7209	function init(gallery, customOptions, isTilesMode){
7210				
7211		g_objects = gallery.getObjects();
7212		g_gallery = gallery;
7213		
7214		g_gallery.attachThumbsPanel("grid", t);
7215		
7216		g_objGallery = jQuery(gallery);
7217		g_objWrapper = g_objects.g_objWrapper;
7218		g_arrItems = g_objects.g_arrItems;
7219		
7220		if(isTilesMode === true)
7221			g_temp.isTilesMode = true;
7222		
7223		g_temp.numThumbs = g_arrItems.length;
7224		
7225		setOptions(customOptions);
7226		
7227		if(g_temp.isTilesMode == true){
7228			
7229			g_tilesDesign.setFixedMode();
7230			g_tilesDesign.setApproveClickFunction(isApproveTileClick);
7231			g_tilesDesign.init(gallery, g_options);
7232			
7233			var options_td = g_tilesDesign.getOptions();
7234			g_temp.tileMaxHeight = options_td.tile_height;
7235			g_temp.tileMaxWidth = options_td.tile_width;
7236			
7237			g_thumbs = g_tilesDesign.getObjThumbs();
7238		}else{
7239			
7240			//disable the dynamic size in thumbs
7241			customOptions.thumb_fixed_size = true;
7242			
7243			g_thumbs.init(gallery, customOptions);
7244		}
7245		
7246	}
7247	
7248	
7249	/**
7250	 * set the grid panel html
7251	 */
7252	function setHtml(parentContainer){
7253		
7254		var objParent = g_objWrapper;
7255		
7256		if(parentContainer)
7257			objParent = parentContainer;
7258		
7259		objParent.append("<div class='ug-thumbs-grid'><div class='ug-thumbs-grid-inner'></div></div>");		 
7260		g_objGrid = objParent.children(".ug-thumbs-grid");
7261		g_objInner = g_objGrid.children(".ug-thumbs-grid-inner");		
7262		
7263		//put the thumbs to inner strip
7264		
7265		if(g_temp.isTilesMode == true)
7266			g_tilesDesign.setHtml(g_objInner);
7267		else
7268			g_thumbs.setHtmlThumbs(g_objInner);
7269		
7270	}
7271	
7272	
7273	/**
7274	 * validate before running the grid
7275	 */
7276	function validateBeforeRun(){
7277		
7278		if(g_temp.isHorizontal == false){	//vertical type			
7279			if(g_temp.gridHeight == 0)
7280				throw new Error("You must set height before run.");		
7281		}else{
7282			if(g_temp.gridWidth == 0)
7283				throw new Error("You must set width before run.");					
7284		}
7285		
7286	}
7287	
7288	
7289	/**
7290	 * run the gallery after init and set html
7291	 */
7292	function run(){
7293		
7294		var selectedItem = g_gallery.getSelectedItem();
7295		
7296		validateBeforeRun();
7297		
7298		if(g_temp.isFirstTimeRun == true){
7299			
7300			initEvents();
7301						
7302			if(g_temp.isTilesMode == true){
7303				
7304				initGridDynamicSize();
7305				initSizeParams();					
7306				g_tilesDesign.run();
7307				
7308			}else{
7309				g_thumbs.setHtmlProperties();
7310				initSizeParams();			
7311				g_thumbs.loadThumbsImages();
7312			}
7313			
7314		}else{
7315			
7316			if(g_temp.isTilesMode == true){
7317				
7318				//check if dynamic size changed. If do, run the thumbs again
7319				var isChanged = initGridDynamicSize();
7320				
7321				if(isChanged == true){
7322					initSizeParams();					
7323					g_tilesDesign.run();
7324				}
7325			}
7326			
7327		}
7328				
7329		positionThumbs();
7330		
7331		if(g_temp.isFirstTimeRun == true && g_temp.isTilesMode){
7332			
7333			var objTiles = g_thumbs.getThumbs();
7334			
7335			//fire size change event
7336			objTiles.each(function(index, tile){
7337				
7338				g_objWrapper.trigger(g_temp.eventSizeChange, jQuery(tile));
7339			});
7340			
7341			objTiles.fadeTo(0,1);
7342		}
7343			
7344		if(selectedItem != null)
7345			scrollToThumb(selectedItem.index);
7346		
7347		//trigger pane change event on the start
7348		g_objThis.trigger(t.events.PANE_CHANGE, g_temp.currentPane);
7349		
7350		g_temp.isFirstTimeRun = false;
7351	}
7352	
7353	/**
7354	 * get thumb size object
7355	 */
7356	function getThumbsSize(){
7357		if(g_temp.isTilesMode == true)
7358			var objThumbSize = g_tilesDesign.getGlobalTileSize();
7359		else
7360			var objThumbSize = g_thumbs.getGlobalThumbSize();
7361		
7362		return(objThumbSize);
7363	}
7364	
7365	
7366	/**
7367	 * init grid dynamic size (tiles mode)
7368	 */
7369	function initGridDynamicSize(){
7370		
7371		if(g_temp.isTilesMode == false)
7372			throw new Error("Dynamic size can be set only in tiles mode");
7373		
7374		var isChanged = false;
7375		var isMobile = g_gallery.isMobileMode();
7376		
7377		//--- set space between cols and rows
7378		
7379		var spaceOld = g_temp.spaceBetweenCols;
7380		
7381		if(isMobile == true){
7382			g_temp.spaceBetweenCols = g_options.grid_space_between_mobile;
7383			g_temp.spaceBetweenRows = g_options.grid_space_between_mobile;
7384		}else{
7385			g_temp.spaceBetweenCols = g_options.grid_space_between_cols;
7386			g_temp.spaceBetweenRows = g_options.grid_space_between_rows;
7387		}
7388		
7389		if(g_temp.spaceBetweenCols != spaceOld)
7390			isChanged = true;
7391		
7392		//set tile size
7393		
7394		var lastThumbSize = getThumbsSize();
7395		var lastThumbWidth = lastThumbSize.width;
7396		
7397		var tileWidth = g_temp.tileMaxWidth;
7398		var numCols = g_functions.getNumItemsInSpace(g_temp.gridWidth, g_temp.tileMaxWidth, g_temp.spaceBetweenCols);
7399		
7400		if(numCols < g_options.grid_min_cols){
7401			tileWidth = g_functions.getItemSizeInSpace(g_temp.gridWidth, g_options.grid_min_cols, g_temp.spaceBetweenCols);
7402		}
7403		
7404		g_tilesDesign.setTileSizeOptions(tileWidth);
7405		
7406		if(tileWidth != lastThumbWidth)
7407			isChanged = true;
7408		
7409		
7410		return(isChanged);
7411	}
7412	
7413	
7414	/**
7415	 * init grid size horizontal
7416	 * get height param
7417	 */
7418	function initSizeParamsHor(){
7419				
7420		var objThumbSize = getThumbsSize();
7421		
7422		var thumbsHeight = objThumbSize.height;
7423		
7424		//set grid size
7425		var gridWidth = g_temp.gridWidth;
7426		var gridHeight = g_options.grid_num_rows * thumbsHeight + (g_options.grid_num_rows-1) * g_temp.spaceBetweenRows + g_options.grid_padding*2;
7427		
7428		g_temp.gridHeight = gridHeight;
7429		
7430		g_functions.setElementSize(g_objGrid, gridWidth, gridHeight);
7431	
7432		//set inner size (as grid size, will be corrected after placing thumbs
7433		g_functions.setElementSize(g_objInner, gridWidth, gridHeight);
7434		
7435		//set initial inner size params
7436		g_temp.innerWidth = gridWidth;
7437		g_temp.innerHeight = gridHeight;
7438	}
7439	
7440	
7441	/**
7442	 * init size params vertical
7443	 */
7444	function initSizeParamsVert(){
7445
7446		var objThumbSize = getThumbsSize();
7447		
7448		var thumbsWidth = objThumbSize.width;
7449		
7450		//set grid size
7451		var gridWidth = g_options.grid_num_cols * thumbsWidth + (g_options.grid_num_cols-1) * g_temp.spaceBetweenCols + g_options.grid_padding*2;
7452		var gridHeight = g_temp.gridHeight;
7453		
7454		g_temp.gridWidth = gridWidth;
7455		
7456		g_functions.setElementSize(g_objGrid, gridWidth, gridHeight);
7457	
7458		//set inner size (as grid size, will be corrected after placing thumbs
7459		g_functions.setElementSize(g_objInner, gridWidth, gridHeight);
7460		
7461		//set initial inner size params
7462		g_temp.innerWidth = gridWidth;
7463		g_temp.innerHeight = gridHeight;
7464		
7465	}
7466	
7467	/**
7468	 * init grid size
7469	 */
7470	function initSizeParams(){
7471		
7472		if(g_temp.isHorizontal == false)
7473			initSizeParamsVert();
7474		else
7475			initSizeParamsHor();
7476		
7477	}
7478
7479	
7480
7481	/**
7482	 * goto pane by index
7483	 */
7484	function scrollToThumb(thumbIndex){
7485		
7486		var paneIndex = getPaneIndexByThumbIndex(thumbIndex);
7487		if(paneIndex == -1)
7488			return(false);
7489				
7490		t.gotoPane(paneIndex, "scroll");
7491				
7492	}
7493	
7494	
7495	/**
7496	 * set the options of the strip
7497	 */
7498	function setOptions(objOptions){
7499		
7500		g_options = jQuery.extend(g_options, objOptions);
7501		
7502		g_thumbs.setOptions(objOptions);
7503		
7504		//set vertical or horizon
7505		g_temp.isNavigationVertical = (g_options.grid_panes_direction == "top" || g_options.grid_panes_direction == "bottom")
7506		
7507		g_temp.spaceBetweenCols = g_options.grid_space_between_cols;
7508		g_temp.spaceBetweenRows = g_options.grid_space_between_rows;
7509		
7510	}
7511	
7512	
7513	/**
7514	 * position the thumbs and init panes horizontally
7515	 */
7516	function positionThumb_hor(){
7517				
7518		var arrThumbs = g_objInner.children(".ug-thumb-wrapper");
7519		
7520		var posx = 0;
7521		var posy = 0;
7522		var counter = 0;
7523		var baseX = 0;
7524		var maxx = 0, maxy = 0;
7525		g_temp.innerWidth = 0;
7526		g_temp.numPanes = 1;
7527		g_temp.arrPanes = [];
7528		g_temp.numThumbsInPane = 0;
7529		
7530		//set first pane position
7531		g_temp.arrPanes.push(baseX);	
7532		
7533		var numThumbs = arrThumbs.length;
7534			
7535		for(i=0;i < numThumbs; i++){
7536			var objThumb = jQuery(arrThumbs[i]);
7537			g_functions.placeElement(objThumb, posx, posy);
7538			
7539			var thumbWidth = objThumb.outerWidth();
7540			var thumbHeight = objThumb.outerHeight();
7541			
7542			//count maxx
7543			if(posx > maxx)
7544				maxx = posx;
7545			
7546			//count maxy
7547			var endY = posy + thumbHeight;
7548			if(endY > maxy)
7549				maxy = endY;
7550			
7551			//count maxx end
7552			var endX = maxx + thumbWidth;
7553			if(endX > g_temp.innerWidth)
7554				g_temp.innerWidth = endX;
7555						
7556			posx += thumbWidth + g_temp.spaceBetweenCols;
7557			
7558			//next row
7559			counter++;
7560			if(counter >= g_options.grid_num_cols){
7561				posy += thumbHeight + g_temp.spaceBetweenRows;
7562				posx = baseX;
7563				counter = 0;
7564			}
7565			
7566			//count number thumbs in pane
7567			if(g_temp.numPanes == 1)
7568				g_temp.numThumbsInPane++;
7569			
7570			//prepare next pane
7571			if((posy + thumbHeight) > g_temp.gridHeight){
7572				posy = 0;
7573				baseX = g_temp.innerWidth + g_temp.spaceBetweenCols;
7574				posx = baseX;
7575				counter = 0;
7576								
7577				//correct max height size (do it once only)
7578				if(g_temp.isMaxHeight == true && g_temp.numPanes == 1){
7579					g_temp.gridHeight = maxy;
7580					g_objGrid.height(g_temp.gridHeight);
7581				}
7582				
7583				//save next pane props (if exists)
7584				if(i < (numThumbs - 1)){
7585					g_temp.numPanes++;
7586					
7587					//set next pane position
7588					g_temp.arrPanes.push(baseX);	
7589										
7590				}
7591			}
7592		}
7593		
7594		
7595		//set inner strip width and height
7596		g_objInner.width(g_temp.innerWidth);
7597		
7598		//set grid height
7599		if(g_temp.isMaxHeight == true && g_temp.numPanes == 1){
7600			g_temp.gridHeight = maxy;
7601			g_objGrid.height(maxy);
7602		}
7603		
7604	}
7605	
7606	
7607	/**
7608	 * position the thumbs and init panes vertically
7609	 */
7610	function positionThumb_vert(){
7611		var arrThumbs = g_objInner.children(".ug-thumb-wrapper");
7612		
7613		var posx = 0;
7614		var posy = 0;
7615		var maxy = 0;
7616		var counter = 0;
7617		var baseX = 0;
7618		var paneStartY = 0;
7619		
7620		g_temp.innerWidth = 0;
7621		g_temp.numPanes = 1;
7622		g_temp.arrPanes = [];
7623		g_temp.numThumbsInPane = 0;
7624		
7625		//set first pane position
7626		g_temp.arrPanes.push(baseX);
7627		
7628		var numThumbs = arrThumbs.length;
7629			
7630		for(i=0;i < numThumbs; i++){
7631			var objThumb = jQuery(arrThumbs[i]);
7632			g_functions.placeElement(objThumb, posx, posy);
7633			
7634			var thumbWidth = objThumb.outerWidth();
7635			var thumbHeight = objThumb.outerHeight();
7636									
7637			posx += thumbWidth + g_temp.spaceBetweenCols;
7638			
7639			var endy = (posy + thumbHeight);
7640			if(endy > maxy)
7641				maxy = endy;
7642			
7643			//next row
7644			counter++;
7645			if(counter >= g_options.grid_num_cols){
7646				posy += thumbHeight + g_temp.spaceBetweenRows;
7647				posx = baseX;
7648				counter = 0;
7649			}
7650			
7651			//count number thumbs in pane
7652			if(g_temp.numPanes == 1)
7653				g_temp.numThumbsInPane++;
7654						
7655			//prepare next pane
7656			endy = (posy + thumbHeight);
7657			var paneMaxY = paneStartY + g_temp.gridHeight;
7658			
7659			//advance next pane
7660			if(endy > paneMaxY){
7661				
7662				//correct max height size (do it once only)
7663				if(g_temp.isMaxHeight == true && g_temp.numPanes == 1){
7664					g_temp.gridHeight = maxy;
7665					g_objGrid.height(g_temp.gridHeight);
7666					paneMaxY = g_temp.gridHeight;
7667				}
7668				
7669				posy = paneMaxY + g_temp.spaceBetweenRows;					
7670				paneStartY = posy;
7671				baseX = 0;
7672				posx = baseX;
7673				counter = 0;
7674				
7675				//save next pane props (if exists)
7676				if(i < (numThumbs - 1)){
7677					g_temp.numPanes++;
7678					
7679					//set next pane position
7680					g_temp.arrPanes.push(posy);	
7681									
7682				}
7683			}
7684			
7685		}//for
7686				
7687		//set inner height 
7688		g_objInner.height(maxy);
7689		g_temp.innerHeight = maxy;
7690		
7691		//set grid height
7692		if(g_temp.isMaxHeight == true && g_temp.numPanes == 1){
7693			g_temp.gridHeight = maxy;
7694			g_objGrid.height(maxy);
7695		}
7696		
7697	}
7698
7699	
7700	/**
7701	 * position the thumbs horizontal type
7702	 */	
7703	function positionThumb_hortype(){
7704				
7705		var arrThumbs = g_objInner.children(".ug-thumb-wrapper");
7706		
7707		var baseX = g_options.grid_padding;
7708		var baseY = g_options.grid_padding;
7709		var posy = baseY;
7710		var posx = baseX;
7711		var maxx = 0, maxy = 0, paneMaxY = 0, gridMaxY = 0;
7712		var rowsCounter = 0;
7713		
7714		g_temp.innerWidth = 0;
7715		g_temp.numPanes = 1;
7716		g_temp.arrPanes = [];
7717		g_temp.numThumbsInPane = 0;
7718		
7719		//set first pane position
7720		g_temp.arrPanes.push(baseX-g_options.grid_padding);	
7721		
7722		var numThumbs = arrThumbs.length;
7723				
7724		for(i=0;i < numThumbs; i++){
7725			var objThumb = jQuery(arrThumbs[i]);
7726			
7727			var thumbWidth = objThumb.outerWidth();
7728			var thumbHeight = objThumb.outerHeight();
7729			
7730			//check end of the size, start a new row
7731			if((posx - baseX + thumbWidth) > g_temp.gridWidth){
7732				rowsCounter++;
7733				posy = 0;
7734				
7735				if(rowsCounter >= g_options.grid_num_rows){
7736					
7737					//change to a new pane					
7738					rowsCounter = 0;
7739					baseX = posx;
7740					posy = baseY;
7741					paneMaxY = 0;
7742					
7743					//change grid width to max width
7744					if(g_temp.numPanes == 1){
7745						g_temp.gridWidth = maxx+g_options.grid_padding;
7746						g_objGrid.width(g_temp.gridWidth);
7747						
7748						g_temp.gridHeight = gridMaxY + g_options.grid_padding;
7749						g_objGrid.height(g_temp.gridHeight);
7750						
7751					}
7752					
7753					g_temp.numPanes++;
7754					g_temp.arrPanes.push(baseX-g_options.grid_padding);
7755					
7756				}else{			//start new line in existing pane
7757					posx = baseX;
7758					posy = paneMaxY + g_temp.spaceBetweenRows;
7759				}
7760			}
7761			
7762			//place the thumb
7763			g_functions.placeElement(objThumb, posx, posy);
7764			
7765			//count maxx
7766			var endX = posx + thumbWidth;
7767			if(endX > maxx)
7768				maxx = endX;
7769			
7770			//count maxy
7771			var endY = posy + thumbHeight;
7772			
7773			if(endY > paneMaxY)		//pane height
7774				paneMaxY = endY;
7775			
7776			if(endY > gridMaxY)		//total height
7777				gridMaxY = endY;
7778			
7779			if(endY > maxy)
7780				maxy = endY;
7781			
7782			//count maxx end
7783			var endX = maxx + thumbWidth;
7784			if(endX > g_temp.innerWidth)
7785				g_temp.innerWidth = endX;
7786						
7787			posx += thumbWidth + g_temp.spaceBetweenCols;
7788						
7789			//count number thumbs in pane
7790			if(g_temp.numPanes == 1)
7791				g_temp.numThumbsInPane++;
7792			
7793			
7794		}//end for
7795		
7796		//set inner strip width and height
7797		g_temp.innerWidth = maxx + g_options.grid_padding;
7798		g_temp.innerHeight = gridMaxY + g_options.grid_padding;
7799		
7800		g_objInner.width(g_temp.innerWidth);
7801		g_objInner.height(g_temp.innerHeight);
7802
7803
7804		//set grid height
7805		if(g_temp.numPanes == 1){
7806			g_temp.gridWidth = maxx + g_options.grid_padding;
7807			g_temp.gridHeight = gridMaxY + g_options.grid_padding;
7808			
7809			g_objGrid.width(g_temp.gridWidth);
7810			g_objGrid.height(g_temp.gridHeight);
7811						
7812		}
7813		
7814			
7815	}
7816	
7817	
7818	/**
7819	 * position the thumbs and init panes related and width related vars
7820	 */
7821	function positionThumbs(){
7822		
7823		if(g_temp.isHorizontal == false){		//position vertical type
7824			
7825			if(g_temp.isNavigationVertical)
7826				positionThumb_vert();
7827			else
7828				positionThumb_hor();
7829			
7830		}else{
7831			positionThumb_hortype();
7832		}
7833		
7834	}
7835	
7836	
7837	/**
7838	 * validate thumb index
7839	 */
7840	function validateThumbIndex(thumbIndex){
7841		
7842		if(thumbIndex < 0 || thumbIndex >= g_temp.numThumbs){
7843			throw new Error("Thumb not exists: " + thumbIndex);
7844			return(false);
7845		}
7846		
7847		return(true);
7848	}
7849	
7850	
7851	/**
7852	 * 
7853	 * validate that the pane index exists
7854	 */
7855	function validatePaneIndex(paneIndex){
7856		
7857		if(paneIndex >= g_temp.numPanes || paneIndex < 0){
7858			throw new Error("Pane " + index + " doesn't exists.");
7859			return(false);
7860		}
7861		
7862		return(true);
7863	}
7864	
7865	/**
7866	 * validate inner position
7867	 */
7868	function validateInnerPos(pos){
7869				
7870		var absPos = Math.abs(pos);
7871		
7872		if(g_temp.isNavigationVertical == false){
7873			
7874			if(absPos < 0 || absPos >= g_temp.innerWidth){
7875				throw new Error("wrong inner x position: " + pos);
7876				return(false);
7877			}
7878			
7879		}else{
7880			
7881			if(absPos < 0 || absPos >= g_temp.innerHeight){
7882				throw new Error("wrong inner y position: " + pos);
7883				return(false);
7884			}
7885			
7886		}
7887		
7888		return(true);
7889	}
7890	
7891	
7892	
7893	
7894	/**
7895	 * 
7896	 * set inner strip position
7897	 */
7898	function setInnerPos(pos){
7899		
7900		var objCss = getInnerPosObj(pos);
7901		if(objCss == false)
7902			return(false);
7903		
7904		g_objInner.css(objCss);
7905	}
7906	
7907	
7908	/**
7909	 * animate inner to some position
7910	 */
7911	function animateInnerTo(pos){
7912		
7913		var objCss = getInnerPosObj(pos);
7914		if(objCss == false)
7915			return(false);
7916		
7917		g_objInner.stop(true).animate(objCss ,{
7918			duration: g_options.grid_transition_duration,
7919			easing: g_options.grid_transition_easing,
7920			queue: false
7921		});
7922		
7923	}
7924	
7925	/**
7926	 * animate back to current pane
7927	 */
7928	function animateToCurrentPane(){
7929		
7930		var innerPos = -g_temp.arrPanes[g_temp.currentPane];
7931		animateInnerTo(innerPos);
7932	}
7933	
7934		
7935	
7936	function __________GETTERS_________(){};
7937	
7938	/**
7939	 * get inner object size according the orientation
7940	 */
7941	function getInnerSize(){
7942		
7943		if(g_temp.isNavigationVertical == true)
7944			return(g_temp.innerHeight);
7945		else
7946			return(g_temp.innerWidth);
7947	}
7948	
7949	
7950	/**
7951	 * get pane width or height according the orientation
7952	 */
7953	function getPaneSize(){
7954		
7955		if(g_temp.isNavigationVertical == true)
7956			return(g_temp.gridHeight);
7957		else
7958			return(g_temp.gridWidth);
7959	}
7960	
7961	
7962	/**
7963	 * get object of iner position move
7964	 */
7965	function getInnerPosObj(pos){
7966				
7967		var obj = {};
7968		if(g_temp.isNavigationVertical == true)
7969			obj.top = pos + "px";
7970		else
7971			obj.left = pos + "px";
7972	
7973		return(obj);
7974	}
7975	
7976	
7977	/**
7978	 * get mouse position according the orientation
7979	 */
7980	function getMousePos(event){
7981		
7982		var mousePos = g_functions.getMousePosition(event);
7983		
7984		if(g_temp.isNavigationVertical == true)
7985			return(mousePos.pageY);
7986		else
7987			return(mousePos.pageX);
7988		
7989	}
7990	
7991	
7992	/**
7993	 * get inner position according the orientation
7994	 */
7995	function getInnerPos(){
7996		
7997		var objSize = g_functions.getElementSize(g_objInner);
7998		
7999		if(g_temp.isNavigationVertical == true)
8000			return(objSize.top);
8001		else
8002			return(objSize.left);
8003	
8004	}
8005	
8006	/**
8007	 * get pane by thumb index
8008	 */
8009	function getPaneIndexByThumbIndex(thumbIndex){
8010		
8011		//validate thumb index
8012		if(validateThumbIndex(thumbIndex) == false)
8013			return(-1);
8014		
8015		var numPane = Math.floor(thumbIndex / g_temp.numThumbsInPane);
8016		
8017		return(numPane);
8018	}
8019	
8020	/**
8021	 * get position of some pane
8022	 */
8023	function getPanePosition(index){
8024								
8025		var pos = g_temp.arrPanes[index];
8026		return(pos);
8027	}
8028	
8029	
8030	/**
8031	 * return if passed some significant movement, for thumb click
8032	 */
8033	function isSignificantPassed(){
8034		
8035		if(g_temp.numPanes == 1)
8036			return(false);
8037		
8038		var objData = g_functions.getStoredEventData(g_temp.storedEventID);
8039		
8040		var passedTime = objData.diffTime;
8041		
8042		var currentInnerPos = getInnerPos();
8043		var passedDistanceAbs = Math.abs(currentInnerPos - objData.startInnerPos);
8044		
8045		if(passedDistanceAbs > 30)
8046			return(true);
8047		
8048		if(passedDistanceAbs > 5 && passedTime > 300)
8049			return(true);
8050				
8051		return(false);
8052	}
8053	
8054	
8055	
8056	/**
8057	 * check if the movement that was held is valid for pane change
8058	 */
8059	function isMovementValidForChange(){
8060		
8061		var objData = g_functions.getStoredEventData(g_temp.storedEventID);
8062		
8063		//check position, if more then half, move
8064		var currentInnerPos = getInnerPos();
8065		diffPos = Math.abs(objData.startInnerPos - currentInnerPos);
8066				
8067		var paneSize = getPaneSize();
8068		var breakSize = Math.round(paneSize * 3 / 8);
8069		
8070		if(diffPos >= breakSize)
8071			return(true);
8072		
8073		if(objData.diffTime < 300 && diffPos > 25)
8074			return(true);
8075						
8076		return(false);
8077	}
8078	
8079	
8080	/**
8081	 * return if passed some significant movement
8082	 */
8083	function isApproveTileClick(){
8084		
8085		if(g_temp.numPanes == 1)
8086			return(true);
8087			
8088		var isApprove = g_functions.isApproveStoredEventClick(g_temp.storedEventID, g_temp.isNavigationVertical);
8089		
8090		return(isApprove);
8091	}
8092	
8093	
8094	function __________EVENTS_______(){};
8095	
8096	
8097	/**
8098	 * on thumb click event
8099	 */
8100	function onThumbClick(event){
8101		
8102		//event.preventDefault();
8103		if(isSignificantPassed() == true)
8104			return(true);
8105		
8106		//run select item operation
8107		var objThumb = jQuery(this);
8108		var objItem = g_thumbs.getItemByThumb(objThumb);
8109		
8110		g_gallery.selectItem(objItem);
8111	}
8112	
8113	
8114	/**
8115	 * on touch start
8116	 */
8117	function onTouchStart(event){
8118				
8119		if(g_temp.numPanes == 1)
8120			return(true);
8121		
8122		if(g_temp.touchActive == true)
8123			return(true);
8124		
8125		if(g_temp.isTilesMode == false)
8126			event.preventDefault();
8127		
8128		g_temp.touchActive = true;
8129		
8130		var addData = {
8131				startInnerPos: getInnerPos()
8132		};
8133		
8134		g_functions.storeEventData(event, g_temp.storedEventID, addData);
8135		
8136	}
8137	
8138	
8139	/**
8140	 * handle scroll top, return if scroll mode or not
8141	 */
8142	function handleScrollTop(){
8143		
8144		if(g_options.grid_vertical_scroll_ondrag == false)
8145			return(false);
8146		
8147		if(g_temp.isNavigationVertical == true)
8148			return(false);
8149		
8150		var scrollDir = g_functions.handleScrollTop(g_temp.storedEventID);
8151		
8152		if(scrollDir === "vert")
8153			return(true);
8154		
8155		return(false);
8156	}
8157	
8158	
8159	/**
8160	 * on touch move
8161	 */
8162	function onTouchMove(event){
8163				
8164		if(g_temp.touchActive == false)
8165			return(true);
8166		
8167		event.preventDefault();
8168		
8169		g_functions.updateStoredEventData(event, g_temp.storedEventID);
8170		
8171		var objData = g_functions.getStoredEventData(g_temp.storedEventID, g_temp.isNavigationVertical);
8172		
8173		//check if was vertical scroll
8174		var isScroll = handleScrollTop();
8175		if(isScroll)
8176			return(true);
8177		
8178		
8179		var diff = objData.diffMousePos;
8180		var innerPos = objData.startInnerPos + diff;
8181		var direction = (diff > 0) ? "prev":"next";
8182		var lastPaneSize = g_temp.arrPanes[g_temp.numPanes-1];
8183		
8184		//slow down when off limits
8185		if(g_options.grid_carousel == false && innerPos > 0 && direction == "prev"){
8186			innerPos = innerPos / 3;
8187		}
8188		
8189		//debugLine({lastSize:lastPaneSize,innerPos: innerPos});
8190		
8191		if(g_options.grid_carousel == false && innerPos < -lastPaneSize && direction == "next"){
8192			innerPos = objData.startInnerPos + diff / 3;
8193		}
8194		
8195		setInnerPos(innerPos);
8196			
8197	}
8198	
8199	
8200	/**
8201	 * on touch end
8202	 * change panes or return to current pane
8203	 */
8204	function onTouchEnd(event){
8205		
8206		if(g_temp.touchActive == false)
8207			return(true);
8208		
8209		g_functions.updateStoredEventData(event, g_temp.storedEventID);
8210		var objData = g_functions.getStoredEventData(g_temp.storedEventID, g_temp.isNavigationVertical);
8211		
8212		//event.preventDefault();
8213		g_temp.touchActive = false;
8214		
8215		if(isMovementValidForChange() == false){
8216			animateToCurrentPane();
8217			return(true);
8218		}
8219		
8220		//move pane or return back
8221		var innerPos = getInnerPos();
8222		var diff = innerPos - objData.startInnerPos;
8223		var direction = (diff > 0) ? "prev":"next";
8224		
8225		if(direction == "next"){
8226						
8227			if(g_options.grid_carousel == false && t.isLastPane())
8228				animateToCurrentPane();
8229			else
8230				t.nextPane();			
8231		}
8232		else{
8233						
8234			if(g_options.grid_carousel == false && t.isFirstPane()){
8235				animateToCurrentPane();
8236			}
8237			else
8238				t.prevPane();
8239		}
8240		
8241	}
8242	
8243	
8244	/**
8245	 * on item change
8246	 */
8247	function onItemChange(){
8248			
8249		var objItem = g_gallery.getSelectedItem();
8250		g_thumbs.setThumbSelected(objItem.objThumbWrapper);
8251		
8252		scrollToThumb(objItem.index);
8253		
8254	}
8255	
8256	
8257	/**
8258	 * init panel events
8259	 */
8260	function initEvents(){
8261		
8262		if(g_temp.isTilesMode == false){
8263			
8264			g_thumbs.initEvents();		
8265			var objThumbs = g_objGrid.find(".ug-thumb-wrapper");
8266			objThumbs.on("click touchend",onThumbClick);
8267			
8268			g_objGallery.on(g_gallery.events.ITEM_CHANGE, onItemChange);
8269			
8270		}else{
8271			g_tilesDesign.initEvents();
8272		}
8273		
8274		//touch drag events
8275		
8276		//slider mouse down - drag start
8277		g_objGrid.bind("mousedown touchstart",onTouchStart);
8278		
8279		//on body move
8280		jQuery("body").bind("mousemove touchmove",onTouchMove);
8281		
8282		//on body mouse up - drag end
8283		jQuery(window).add("body").bind("mouseup touchend", onTouchEnd);
8284		
8285	}
8286	
8287	
8288	/**
8289	 * destroy the events
8290	 */
8291	this.destroy = function(){
8292		
8293		if(g_temp.isTilesMode == false){
8294			
8295			var objThumbs = g_objGrid.find(".ug-thumb-wrapper");
8296			objThumbs.off("click");
8297			objThumbs.off("touchend");
8298			g_objGallery.on(g_gallery.events.ITEM_CHANGE);
8299			g_thumbs.destroy();		
8300						
8301		}else{
8302			g_tilesDesign.destroy();
8303		}
8304		
8305		g_objGrid.unbind("mousedown");
8306		g_objGrid.unbind("touchstart");
8307		jQuery("body").unbind("mousemove");
8308		jQuery("body").unbind("touchmove");
8309		
8310		jQuery(window).add("body").unbind("touchend");
8311		jQuery(window).add("body").unbind("mouseup");
8312		
8313		g_objThis.off(t.events.PANE_CHANGE);
8314		
8315	}
8316	
8317	
8318	
8319	this.__________EXTERNAL_GENERAL_________ = function(){};
8320	
8321	/**
8322	 * set the thumb unselected state
8323	 */
8324	this.setThumbUnselected = function(objThumbWrapper){
8325		
8326		g_thumbs.setThumbUnselected(objThumbWrapper);
8327		
8328	}
8329	
8330	/**
8331	 * check if thmb item visible, means inside the visible part of the inner strip
8332	 */
8333	this.isItemThumbVisible = function(objItem){
8334		var itemIndex = objItem.index;
8335		var paneIndex = getPaneIndexByThumbIndex(itemIndex);
8336		
8337		if(paneIndex == g_temp.currentPane)
8338			return(true);
8339		
8340		return(false);
8341	}
8342	
8343	
8344	this.__________EXTERNAL_API_________ = function(){};
8345	
8346	/**
8347	 * get estimation of number of panes by the height of the grid.
8348	 */
8349	this.getNumPanesEstimationByHeight = function(gridHeight){
8350		
8351		if(g_temp.isTilesMode == true){
8352			
8353			var thumbHeight = g_options.tile_height;
8354			
8355		}else{
8356			var thumbsOptions = g_thumbs.getOptions();		
8357			var thumbHeight = thumbsOptions.thumb_height;
8358		}
8359		
8360		var numThumbs = g_thumbs.getNumThumbs();
8361		var numRows = Math.ceil(numThumbs / g_options.grid_num_cols);
8362		
8363		var totalHeight = numRows * thumbHeight + (numRows-1) * g_temp.spaceBetweenRows;
8364			
8365		var numPanes = Math.ceil(totalHeight / gridHeight);
8366		
8367		return(numPanes);
8368	}
8369	
8370	/**
8371	 * get estimation of number of panes by the width of the grid.
8372	 */
8373	this.getNumPanesEstimationByWidth = function(gridWidth){
8374		
8375		if(g_temp.isTilesMode){
8376			var thumbWidth = g_options.tile_width;			
8377		}else{
8378			var thumbsOptions = g_thumbs.getOptions();		
8379			var thumbWidth = thumbsOptions.thumb_width;
8380		}
8381		
8382		var numThumbs = g_thumbs.getNumThumbs();
8383		var numCols = Math.ceil(numThumbs / g_options.grid_num_rows);
8384		
8385		var totalWidth = numCols * thumbWidth + (numCols-1) * g_temp.spaceBetweenCols;
8386		
8387		var numPanes = Math.ceil(totalWidth / gridWidth);
8388				
8389		return(numPanes);
8390	}
8391	
8392	
8393	/**
8394	 * get height estimation by width, works only in tiles mode
8395	 */
8396	this.getHeightEstimationByWidth = function(width){
8397		
8398		if(g_temp.isTilesMode == false)
8399			throw new Error("This function works only with tiles mode");
8400		
8401		var numThumbs = g_thumbs.getNumThumbs();
8402		var numCols = g_functions.getNumItemsInSpace(width, g_options.tile_width, g_temp.spaceBetweenCols);
8403		var numRows = Math.ceil(numThumbs / numCols);
8404		
8405		if(numRows > g_options.grid_num_rows)
8406			numRows = g_options.grid_num_rows;
8407		
8408		var gridHeight = g_functions.getSpaceByNumItems(numRows, g_options.tile_height, g_temp.spaceBetweenRows);
8409		gridHeight += g_options.grid_padding * 2;
8410		
8411		return(gridHeight);
8412	}
8413	
8414	/**
8415	 * get the grid element
8416	 */
8417	this.getElement = function(){
8418		return(g_objGrid);
8419	}
8420	
8421	/**
8422	 * get element size and position
8423	 */
8424	this.getSize = function(){
8425		
8426		var objSize = g_functions.getElementSize(g_objGrid);
8427		return(objSize);
8428		
8429	}
8430	
8431	/**
8432	 * get number of panes
8433	 */
8434	this.getNumPanes = function(){
8435		
8436		return(g_temp.numPanes);
8437	}
8438	
8439	/**
8440	 * get if the current pane is first
8441	 */
8442	this.isFirstPane = function(){
8443		
8444		if(g_temp.currentPane == 0)
8445			return(true);
8446		
8447		return(false);
8448	}
8449	
8450	
8451	/**
8452	 * get if the current pane is last
8453	 */
8454	this.isLastPane = function(){
8455		
8456		if(g_temp.currentPane == (g_temp.numPanes -1) )
8457			return(true);
8458		
8459		return(false);
8460	}
8461	
8462	
8463	/**
8464	 * get pane number, and num panes
8465	 */
8466	this.getPaneInfo = function(){
8467		
8468		var obj = {
8469			pane: g_temp.currentPane,
8470			total: g_temp.numPanes
8471		};
8472		
8473		return(obj);
8474	}
8475	
8476	
8477	/**
8478	 * get current pane
8479	 */
8480	this.getPane = function(){
8481		
8482		return(g_temp.currentPane);
8483	}
8484	
8485	
8486	/**
8487	 * set grid width (horizontal type)
8488	 */
8489	this.setWidth = function(gridWidth){
8490		g_temp.gridWidth = gridWidth;
8491		g_temp.isHorizontal = true;
8492	}
8493	
8494	/**
8495	 * set max width, the width will be corrected by the number of items
8496	 * set vertical type
8497	 */
8498	this.setMaxWidth = function(maxWidth){
8499		g_temp.gridWidth = maxWidth;
8500		g_temp.isMaxWidth = true;
8501		g_temp.isHorizontal = true;
8502	}
8503	
8504	
8505	/**
8506	 * set grid height (vertical type)
8507	 */
8508	this.setHeight = function(gridHeight){
8509		g_temp.gridHeight = gridHeight;
8510		g_temp.isHorizontal = false;
8511		
8512	}
8513	
8514	/**
8515	 * set max height, the height will be corrected by the number of items
8516	 * set the vertical type
8517	 */
8518	this.setMaxHeight = function(maxHeight){
8519		g_temp.gridHeight = maxHeight;
8520		g_temp.isMaxHeight = true;
8521		g_temp.isHorizontal = false;
8522	}
8523	
8524	
8525	/**
8526	 * goto some pane
8527	 * force skip current pane checks
8528	 */
8529	this.gotoPane = function(index, fromWhere){
8530		
8531		if(validatePaneIndex(index) == false)
8532			return(false);
8533		
8534		if(index == g_temp.currentPane)
8535			return(false);
8536		
8537		var innerPos = -g_temp.arrPanes[index];
8538		
8539		g_temp.currentPane = index;
8540		animateInnerTo(innerPos);
8541		
8542		//trigger pane change event
8543		g_objThis.trigger(t.events.PANE_CHANGE, index);
8544	}
8545	
8546	
8547	/**
8548	 * foreward to the next pane
8549	 */
8550	this.nextPane = function(){
8551				
8552		var nextPaneIndex = g_temp.currentPane+1;
8553		
8554		if(nextPaneIndex >= g_temp.numPanes){
8555			
8556			if(g_options.grid_carousel == false)
8557				return(true);
8558			
8559			nextPaneIndex = 0;
8560		}
8561		
8562		t.gotoPane(nextPaneIndex, "next");
8563	}
8564	
8565	
8566	/**
8567	 * foreward to the next pane
8568	 */
8569	this.prevPane = function(){
8570		
8571		var prevPaneIndex = g_temp.currentPane-1;
8572		if(prevPaneIndex < 0){
8573			prevPaneIndex = g_temp.numPanes-1;
8574			
8575			if(g_options.grid_carousel == false)
8576				return(false);
8577		}
8578		
8579		t.gotoPane(prevPaneIndex, "prev");
8580	}
8581	
8582	
8583	/**
8584	 * set next pane button
8585	 */
8586	this.attachNextPaneButton = function(objButton){
8587		
8588		g_functions.setButtonOnClick(objButton, t.nextPane);
8589
8590		if(g_options.grid_carousel == true)		
8591			return(true);
8592		
8593		if(t.isLastPane())
8594			objButton.addClass("ug-button-disabled");
8595		
8596		//set disabled button class if first pane
8597		g_objThis.on(t.events.PANE_CHANGE, function(){
8598			
8599			if(t.isLastPane())
8600				objButton.addClass("ug-button-disabled");
8601			else
8602				objButton.removeClass("ug-button-disabled");
8603	
8604		});
8605		
8606	}
8607	
8608	
8609	/**
8610	 * set prev pane button
8611	 */
8612	this.attachPrevPaneButton = function(objButton){
8613				
8614		g_functions.setButtonOnClick(objButton, t.prevPane);
8615		
8616		if(g_options.grid_carousel == true)		
8617			return(true);
8618		
8619		if(t.isFirstPane())
8620			objButton.addClass("ug-button-disabled");
8621		
8622		//set disabled button class if first pane
8623		g_objThis.on(t.events.PANE_CHANGE, function(){
8624			
8625			if(t.isFirstPane())
8626				objButton.addClass("ug-button-disabled");
8627			else
8628				objButton.removeClass("ug-button-disabled");
8629	
8630		});
8631		
8632	}
8633	
8634	
8635	/**
8636	 * attach bullets object
8637	 */
8638	this.attachBullets = function(objBullets){
8639		
8640		objBullets.setActive(g_temp.currentPane);
8641		
8642		jQuery(objBullets).on(objBullets.events.BULLET_CLICK, function(data, numBullet){
8643			t.gotoPane(numBullet, "theme");
8644			objBullets.setActive(numBullet);				
8645		});
8646		
8647		jQuery(t).on(t.events.PANE_CHANGE, function(data, numPane){
8648			objBullets.setActive(numPane);
8649		});
8650		
8651	}
8652	
8653	
8654	/**
8655	 * get tile design object
8656	 */
8657	this.getObjTileDesign = function(){
8658		return g_tilesDesign;
8659	}
8660	
8661	
8662	/**
8663	 * init function 
8664	 */
8665	this.init = function(gallery, customOptions, isTilesMode){
8666		
8667		init(gallery, customOptions, isTilesMode);
8668	}
8669	
8670		
8671	
8672	/**
8673	 * set html and properties
8674	 */	
8675	this.run = function(){
8676		run();
8677	}
8678
8679	
8680	/**
8681	 * set html 
8682	 */
8683	this.setHtml = function(parentContainer){
8684		
8685		setHtml(parentContainer);
8686	}
8687	
8688}
8689
8690
8691
8692/**
8693 * tiles class
8694 */
8695function UGTiles(){
8696
8697	var t = this, g_objThis = jQuery(this);
8698	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objWrapper, g_objParent;	
8699	var g_functions = new UGFunctions(), g_arrItems, g_objTileDesign = new UGTileDesign();
8700	var g_thumbs = new UGThumbsGeneral(), g_vars = {};
8701    var g_arrNestedGridRow, g_arrNestedItems;
8702	
8703	
8704	var g_options = {
8705		 tiles_type: "columns",					//columns / justified - tiles layout type
8706		 tiles_col_width: 250,					//column width - exact or base according the settings
8707		 tiles_align:"center",					//align of the tiles in the space
8708		 tiles_exact_width: false,				//exact width of column - disables the min and max columns
8709		 tiles_space_between_cols: 3,			//space between images
8710		 tiles_space_between_cols_mobile: 3,    //space between cols for mobile type
8711		 tiles_include_padding: true,			//include padding at the sides of the columns, equal to current space between cols
8712		 tiles_min_columns: 2,					//min columns
8713		 tiles_max_columns: 0,					//max columns (0 for unlimited)
8714		 tiles_keep_order: false,				//keep order - slower algorytm
8715		 tiles_set_initial_height: true,		//set some estimated height before images show
8716		 
8717		 tiles_justified_row_height: 150,		//base row height of the justified type
8718		 tiles_justified_space_between: 3,		//space between the tiles justified type
8719
8720		 tiles_nested_optimal_tile_width: 250,	// tiles optimal width
8721	     tiles_nested_col_width: null,			// nested tiles column width
8722	     tiles_nested_debug: false,
8723	     
8724		 tiles_enable_transition: true			//enable transition when screen width change
8725	};
8726	
8727	this.events = {
8728			THUMB_SIZE_CHANGE: "thumb_size_change",
8729			TILES_FIRST_PLACED: "tiles_first_placed",		//only in case of justified
8730			ALL_TILES_LOADED: "all_tiles_loaded"
8731	};
8732	
8733	var g_temp = {
8734			isFirstTimeRun:true,   //if run once
8735			handle:null,		   //interval handle
8736			isTransActive: false,  //is transition active
8737			isTransInited: false,  //if the transition function is set
8738			isFirstPlaced: true,   //is first time placed
8739			isAllLoaded: false
8740	};
8741	
8742    var g_nestedWork = {
8743    		colWidth: null,
8744            nestedOptimalCols: 5,
8745            gridY: 0,
8746            maxColumns: 0,						 //maxColumns
8747            columnsValueToEnableHeightResize: 3, //columns Value To Enable Height Resize
8748            resizeLeftRightToColumn: true,
8749            currentItem: 0,
8750	        currentGap: null,
8751	        optimalTileWidth: null,
8752	        maxGridY:0
8753    }
8754	
8755	
8756	function __________GENERAL_________(){};
8757	
8758	
8759	/**
8760	 * init the gallery
8761	 */
8762	function init(gallery, customOptions){
8763		
8764		g_objects = gallery.getObjects();
8765		g_gallery = gallery;
8766		g_objGallery = jQuery(gallery);
8767		g_objWrapper = g_objects.g_objWrapper;
8768		g_arrItems = g_objects.g_arrItems;
8769		
8770		g_options = jQuery.extend(g_options, customOptions);
8771
8772		modifyOptions();
8773		
8774		g_objTileDesign.init(gallery, g_options);
8775		
8776		g_thumbs = g_objTileDesign.getObjThumbs();
8777		
8778	}
8779	
8780	
8781	/**
8782	 * modify options
8783	 */
8784	function modifyOptions(){
8785		
8786		if(g_options.tiles_min_columns < 1)
8787			g_options.tiles_min_columns = 1;
8788		
8789		//protection of max columns, can't be more then min columns
8790		if(g_options.tiles_max_columns != 0 && g_options.tiles_max_columns < g_options.tiles_min_columns){
8791			g_options.tiles_max_columns = g_options.tiles_min_columns;
8792		}
8793		
8794	}
8795	
8796	
8797	/**
8798	 * set the grid panel html
8799	 */
8800	function setHtml(objParent){
8801		
8802		if(!objParent){
8803			if(g_objParent)
8804				objParent = g_objParent;
8805			else
8806				var objParent = g_objWrapper;
8807		}
8808		
8809		g_objParent = objParent;
8810		
8811		var tilesType = g_options.tiles_type;
8812		objParent.addClass("ug-tiletype-"+tilesType);
8813		
8814		g_objTileDesign.setHtml(objParent);
8815		
8816		objParent.children(".ug-thumb-wrapper").hide();
8817	}
8818	
8819	
8820	/**
8821	 * set class that enables transition
8822	 */
8823	function setTransition(){
8824		
8825		//set the tiles in resting mode, to activate their own transitions
8826		g_objParent.addClass("ug-tiles-rest-mode");
8827		
8828		g_temp.isTransInited = true;
8829		
8830		//add css tansition
8831		if(g_options.tiles_enable_transition == true){
8832			g_objParent.addClass("ug-tiles-transit");
8833			
8834			//add image overlay transition
8835			var optionsTile = g_objTileDesign.getOptions();
8836			
8837			if(optionsTile.tile_enable_image_effect == true && optionsTile.tile_image_effect_reverse == false)
8838				g_objParent.addClass("ug-tiles-transit-overlays");
8839			
8840			g_temp.isTransActive = true;
8841		}
8842		
8843	}
8844	
8845	
8846	/**
8847	 * get parent width
8848	 */
8849	function getParentWidth(){
8850		return g_functions.getElementSize(g_objParent).width;
8851	}
8852	
8853	
8854	/**
8855	 * do some actions before transition
8856	 */
8857	function doBeforeTransition(){
8858		
8859		if(g_temp.isTransInited == false)
8860			return(false);
8861			
8862		g_objParent.addClass("ug-tiles-transition-active");
8863		g_objParent.removeClass("ug-tiles-rest-mode");
8864		
8865		//prepare for transition
8866		if(g_temp.isTransActive == false)
8867			return(false);
8868				
8869		g_objTileDesign.disableEvents();
8870	}
8871	
8872	
8873	/**
8874	 * set after transition classes
8875	 */
8876	function doAfterTransition_setClasses(){
8877		
8878		if(g_temp.isTransInited == false)
8879			return(false);
8880		
8881		g_objParent.removeClass("ug-tiles-transition-active");
8882		g_objParent.addClass("ug-tiles-rest-mode");
8883	}
8884	
8885	
8886	/**
8887	 * do some actions after transition
8888	 */
8889	function doAfterTransition(){
8890
8891		
8892		if(g_temp.isTransActive == true){
8893						
8894			//trigger size change after transition
8895			setTimeout(function(){
8896				
8897				g_objTileDesign.enableEvents();
8898				g_objTileDesign.triggerSizeChangeEventAllTiles();
8899				
8900				doAfterTransition_setClasses();
8901				
8902
8903			}, 800);
8904			
8905			//control size change 
8906			if(g_temp.handle)
8907				clearTimeout(g_temp.handle);
8908				
8909			g_temp.handle = setTimeout(function(){
8910				
8911				doAfterTransition_setClasses();
8912				
8913				g_objTileDesign.triggerSizeChangeEventAllTiles();
8914				g_temp.handle = null;
8915								
8916			}, 2000);
8917			
8918			
8919		}else{
8920						
8921			g_objTileDesign.triggerSizeChangeEventAllTiles();
8922
8923			doAfterTransition_setClasses();
8924
8925		}
8926
8927	}
8928
8929	
8930	function __________COLUMN_TYPE_RELATED_________(){};
8931	
8932	/**
8933	 * count width by number of columns
8934	 */
8935	function fillTilesVars_countWidthByCols(){
8936
8937		g_vars.colWidth = (g_vars.availWidth - g_vars.colGap * (g_vars.numCols-1)) / g_vars.numCols;
8938		g_vars.colWidth = Math.floor(g_vars.colWidth);
8939
8940		g_vars.totalWidth = g_functions.getSpaceByNumItems(g_vars.numCols, g_vars.colWidth, g_vars.colGap);
8941		
8942	}
8943	
8944	
8945	
8946	/**
8947	 * fill common tiles vars
8948	 */
8949	function fillTilesVars(){
8950		
8951		g_vars.colWidth = g_options.tiles_col_width;
8952		g_vars.minCols = g_options.tiles_min_columns;
8953		g_vars.maxCols = g_options.tiles_max_columns;
8954		
8955		if(g_gallery.isMobileMode() == false){
8956			g_vars.colGap = g_options.tiles_space_between_cols;
8957		} else {
8958			g_vars.colGap = g_options.tiles_space_between_cols_mobile;
8959		}
8960		
8961		//set gallery width
8962		g_vars.galleryWidth = getParentWidth();
8963		
8964		g_vars.availWidth = g_vars.galleryWidth;
8965		
8966		if(g_options.tiles_include_padding == true)
8967			g_vars.availWidth = g_vars.galleryWidth - g_vars.colGap*2;
8968		
8969		//set the column number by exact width
8970		if(g_options.tiles_exact_width == true){
8971			
8972			g_vars.numCols = g_functions.getNumItemsInSpace(g_vars.availWidth, g_vars.colWidth, g_vars.colGap);
8973
8974			if(g_vars.maxCols > 0 && g_vars.numCols > g_vars.maxCols)
8975				g_vars.numCols = g_vars.maxCols;
8976
8977			//if less then min cols count width by cols
8978			if(g_vars.numCols < g_vars.minCols){
8979				g_vars.numCols = g_vars.minCols;
8980
8981				fillTilesVars_countWidthByCols();
8982				
8983			}else{
8984				g_vars.totalWidth = g_vars.numCols * (g_vars.colWidth + g_vars.colGap) - g_vars.colGap;
8985			}
8986			
8987		} else {
8988			
8989			//set dynamic column number
8990			
8991			var numCols = g_functions.getNumItemsInSpaceRound(g_vars.availWidth, g_vars.colWidth, g_vars.colGap);
8992						
8993			if(numCols < g_vars.minCols)
8994				numCols = g_vars.minCols;
8995			else
8996				if(g_vars.maxCols != 0 && numCols > g_vars.maxCols)
8997					numCols = g_vars.maxCols;
8998
8999			g_vars.numCols = numCols;
9000			
9001			fillTilesVars_countWidthByCols();
9002			
9003		}
9004
9005		switch(g_options.tiles_align){
9006			case "center":
9007			default:
9008				//add x to center point
9009				g_vars.addX = Math.round( (g_vars.galleryWidth - g_vars.totalWidth) / 2 );
9010			break;
9011			case "left":
9012				g_vars.addX = 0;
9013			break;
9014			case "right":
9015				g_vars.addX = g_vars.galleryWidth - g_vars.totalWidth;
9016			break;
9017		}
9018				
9019		//get posx array (constact to all columns)
9020		g_vars.arrPosx = [];		
9021		for(col = 0; col < g_vars.numCols; col++){
9022			var colX = g_functions.getColX(col, g_vars.colWidth, g_vars.colGap);
9023			g_vars.arrPosx[col] = colX + g_vars.addX;
9024		}
9025		
9026	}
9027	
9028	
9029	/**
9030	 * init col heights
9031	 */
9032	function initColHeights(){
9033		
9034		g_vars.maxColHeight = 0;
9035		
9036		//empty heights array
9037		g_vars.colHeights = [0];
9038		
9039	}
9040	
9041	
9042	
9043	/**
9044	 * get column with minimal height
9045	 */
9046	function getTilesMinCol(){
9047		var numCol = 0;
9048		
9049		var minHeight = 999999999;
9050		
9051		for(col = 0; col < g_vars.numCols; col++){
9052			
9053			if(g_vars.colHeights[col] == undefined || g_vars.colHeights[col] == 0)
9054				return col;
9055			
9056			if(g_vars.colHeights[col] < minHeight){
9057				numCol = col;
9058				minHeight = g_vars.colHeights[col];
9059			}
9060		
9061		}
9062		
9063		return(numCol);
9064	}
9065	
9066	
9067	/**
9068	 * place tile as it loads
9069	 */
9070	function placeTile(objTile, toShow, setGalleryHeight, numCol){
9071		
9072		if(numCol === null || typeof numCol == "undefined")
9073			var numCol = getTilesMinCol();
9074		
9075		//set posy
9076		var posy = 0;
9077		if(g_vars.colHeights[numCol] !== undefined)
9078			posy = g_vars.colHeights[numCol];
9079		
9080		var itemHeight = g_objTileDesign.getTileHeightByWidth(g_vars.colWidth, objTile);
9081		
9082		if(itemHeight === null){	//for custom html tile
9083			if(g_options.tiles_enable_transition == true)
9084				throw new Error("Can't know tile height, please turn off transition");
9085			
9086			var itemSize = g_functions.getElementSize(objTile);
9087			itemHeight = itemSize.height;
9088		}
9089		
9090		var posx = g_vars.arrPosx[numCol];
9091		
9092		g_functions.placeElement(objTile, posx, posy);
9093		
9094		var realHeight = posy + itemHeight;
9095				
9096		g_vars.colHeights[numCol] = realHeight + g_vars.colGap;
9097		
9098		//set max height
9099		if(g_vars.maxColHeight < realHeight)
9100			g_vars.maxColHeight = realHeight;
9101
9102		if(toShow == true)
9103			objTile.show().fadeTo(0,1);
9104		
9105		if(setGalleryHeight == true){
9106			g_objParent.height(g_vars.maxColHeight);			
9107		}
9108		
9109	}
9110	
9111	
9112	/**
9113	 * place the tiles
9114	 */
9115	function placeTiles(toShow){
9116		
9117		if(!toShow)
9118			toShow = false;
9119		
9120		fillTilesVars();
9121		initColHeights();
9122		
9123		var objThumbs = g_thumbs.getThumbs(g_thumbs.type.GET_THUMBS_RATIO);
9124				
9125		//do some operation before the transition
9126		doBeforeTransition();
9127		
9128		//resize all thumbs
9129		g_objTileDesign.resizeAllTiles(g_vars.colWidth, g_objTileDesign.resizemode.VISIBLE_ELEMENTS, objThumbs);
9130		
9131		//place elements
9132		for(var index = 0; index < objThumbs.length; index++){
9133			var objTile = jQuery(objThumbs[index]);
9134			var col = undefined;
9135			if(g_options.tiles_keep_order == true)
9136				col = g_functions.getColByIndex(g_vars.numCols, index);
9137			
9138			placeTile(objTile, toShow, false, col);
9139		}
9140		
9141		//bring back the state after transition
9142		doAfterTransition();
9143		
9144		//set gallery height, according the transition
9145		var galleryHeight = g_objParent.height();
9146		
9147		if(g_temp.isTransActive == true && galleryHeight > g_vars.maxColHeight)
9148			setTimeout(function(){
9149				g_objParent.height(g_vars.maxColHeight);
9150			},700);
9151		else
9152			g_objParent.height(g_vars.maxColHeight);
9153	}
9154	
9155	
9156	/**
9157	 * check if alowed to place ordered tile
9158	 */
9159	function isOrderedTilePlaceAlowed(objTile){
9160		
9161		var index = objTile.index();
9162
9163		//don't allow double put items
9164		var currentItem = g_gallery.getItem(index);
9165		if(currentItem.ordered_placed === true)
9166			return(false);
9167
9168		
9169		var prevIndex = g_functions.getPrevRowSameColIndex(index, g_vars.numCols);
9170
9171		//put first item in the column
9172		if(prevIndex < 0)
9173			return(true);
9174				
9175		//check if previous tile in column is placed
9176		var objPrevItem = g_gallery.getItem(prevIndex);
9177		if(objPrevItem.ordered_placed === true)
9178			return(true);
9179		
9180		return(false);
9181	}
9182	
9183	
9184	/**
9185	 * place ordered tile
9186	 */
9187	function placeOrderedTile(objTile, isForce){
9188		
9189		if(isForce !== true){
9190
9191			var isAlowed = isOrderedTilePlaceAlowed(objTile);
9192			
9193			if(isAlowed == false)
9194				return(false);
9195		}
9196			
9197		var index = objTile.index();
9198				
9199		var col = g_functions.getColByIndex(g_vars.numCols, index);
9200
9201		var objItem = g_gallery.getItem(index);
9202		
9203		g_objTileDesign.resizeTile(objTile, g_vars.colWidth);
9204		
9205		placeTile(objTile, true, true, col);
9206		
9207		objItem.ordered_placed = true;
9208		
9209		//check by recursion and place next items in column
9210		var numItems = g_gallery.getNumItems();
9211		var nextIndex = g_functions.getNextRowSameColIndex(index, g_vars.numCols);
9212		if(nextIndex >= numItems)
9213			return(false);
9214		
9215		var nextTile = g_thumbs.getThumbByIndex(nextIndex);
9216		var nextItem = g_gallery.getItem(nextIndex);
9217		
9218		var isLoaded = g_thumbs.isThumbLoaded(nextTile);
9219		
9220		if(g_thumbs.isThumbLoaded(nextTile) && !nextItem.ordered_placed)
9221			placeOrderedTile(nextTile, true);
9222	}
9223	
9224	
9225	/**
9226	 * on single image load
9227	 */
9228	function onSingleImageLoad(objImage, isError){
9229		
9230		if(isError == true)
9231			return(false);
9232		
9233		objImage = jQuery(objImage);
9234		var objTile = jQuery(objImage).parent();
9235		
9236		g_thumbs.triggerImageLoadedEvent(objTile, objImage);
9237		
9238		if(g_options.tiles_keep_order == true){
9239
9240			placeOrderedTile(objTile);
9241		
9242		}else{
9243						
9244			g_objTileDesign.resizeTile(objTile, g_vars.colWidth);
9245			placeTile(objTile, true, true);
9246		}
9247	
9248	}
9249	
9250	
9251	/**
9252	 * run columns type - place tiles that are not loaded yet
9253	 */
9254	function runColumnsType(){
9255		
9256		//get thumbs only when the ratio not set
9257		var objThumbs = g_thumbs.getThumbs(g_thumbs.type.GET_THUMBS_NO_RATIO);
9258		
9259		if(!objThumbs || objThumbs.length == 0)
9260			return(false);
9261		
9262		g_temp.isAllLoaded = false;
9263				
9264		if(g_temp.isFirstPlaced == true){
9265			
9266			fillTilesVars();
9267			initColHeights();
9268			
9269			var diffWidth = Math.abs(g_vars.galleryWidth - g_vars.totalWidth);
9270			
9271			//set initial height of the parent by estimation
9272			if(g_options.tiles_set_initial_height == true && g_functions.isScrollbarExists() == false && diffWidth < 25){
9273				
9274				var numThumbs = objThumbs.length;
9275				var numRows = Math.ceil(objThumbs.length / g_vars.numCols);
9276				var estimateHeight = numRows * g_options.tiles_col_width * 0.75;
9277				
9278				g_objParent.height(estimateHeight);
9279				fillTilesVars();
9280			}
9281			
9282		}
9283		
9284		
9285		objThumbs.fadeTo(0,0);
9286		var objImages = objThumbs.find("img.ug-thumb-image");
9287		
9288		var initNumCols = g_vars.numCols;
9289		var initWidth = g_vars.galleryWidth;
9290		
9291		//on place the tile as it loads. After all tiles loaded,check position again.
9292		g_functions.checkImagesLoaded(objImages, function(){
9293						
9294			fillTilesVars();
9295			
9296			if(initNumCols != g_vars.numCols || initWidth != g_vars.galleryWidth){
9297				placeTiles(false);
9298			}
9299			
9300			setTransition();
9301			g_objThis.trigger(t.events.ALL_TILES_LOADED);
9302			
9303		} ,function(objImage, isError){
9304			
9305			if(g_temp.isFirstPlaced == true)
9306				g_gallery.triggerEvent(t.events.TILES_FIRST_PLACED);	//set to false
9307			
9308			onSingleImageLoad(objImage, isError);
9309		
9310		});
9311					
9312		
9313	}
9314	
9315	
9316	function __________JUSTIFIED_TYPE_RELATED_________(){};
9317
9318	/**
9319	 * ------------ JUSTIFIED TYPE RELATED FUNCTIONS ----------------
9320	 */
9321	
9322	function getJustifiedData(){
9323		
9324		var galleryWidth = getParentWidth();
9325		
9326		var objTiles = g_thumbs.getThumbs(true);
9327		var rowHeightOpt = g_options.tiles_justified_row_height;
9328		var arrWidths = [];
9329		var totalWidth = 0;
9330		var gap = g_options.tiles_justified_space_between;
9331		var numTiles = objTiles.length;
9332		
9333		//get arr widths and total width
9334		jQuery.each(objTiles, function(index, objTile){
9335			objTile = jQuery(objTile);
9336			
9337			var objItem = g_thumbs.getItemByThumb(objTile);
9338			
9339			var tileWidth = objItem.thumbWidth;
9340			var tileHeight = objItem.thumbHeight;
9341			
9342			if (tileHeight !== rowHeightOpt) 
9343				tileWidth = Math.floor(objItem.thumbRatioByWidth * rowHeightOpt);
9344			
9345			arrWidths[index] = tileWidth;
9346			
9347			totalWidth += tileWidth;
9348		});
9349
9350		
9351		var numRows = Math.ceil(totalWidth / galleryWidth);
9352		
9353		if(numRows > numTiles)
9354			numRows = numTiles;
9355		
9356		var finalRowWidth = totalWidth / numRows;
9357		
9358		//fill rows array, break tiles to rows
9359		var arrRows = [], eachRowWidth = 0;
9360		var rowsWidths = [], rowsTiles = [], row = [];
9361		var progressWidth = 0, numRow = 0;
9362		
9363		jQuery.each(objTiles, function(index, objTile){
9364			var tileWidth = arrWidths[index];
9365						
9366			if( (progressWidth + tileWidth / 2) > (numRow+1) * finalRowWidth){
9367				
9368				rowsWidths[arrRows.length] = eachRowWidth;				
9369				arrRows.push(row);
9370				row = [];
9371				eachRowWidth = 0;
9372				numRow++;
9373			}
9374			
9375			progressWidth += tileWidth;
9376			eachRowWidth += tileWidth;
9377			
9378			row.push(objTile);
9379		});
9380		
9381		rowsWidths[arrRows.length] = eachRowWidth;
9382		arrRows.push(row);
9383				
9384		
9385		//set heights and position images:	
9386		var arrRowWidths = [];
9387		var arrRowHeights = [];
9388		var totalHeight = 0;
9389		
9390		jQuery.each(arrRows, function(index, row){
9391			
9392			var numTiles = row.length;
9393			var rowWidth = rowsWidths[index];
9394			
9395			var gapWidth = (row.length-1) * gap;
9396
9397			var ratio = (galleryWidth - gapWidth) / rowWidth;
9398			var rowHeight = Math.round(rowHeightOpt * ratio);
9399			
9400			//count total height
9401			totalHeight += rowHeight;
9402			if(index > 0)
9403				totalHeight += gap;
9404			
9405			arrRowHeights.push(rowHeight);
9406			
9407			//ratio between 2 heights for fixing image width:
9408            var ratioHeights = rowHeight / rowHeightOpt;
9409			
9410            //set tiles sizes:
9411            var arrRowTileWidths = [];
9412            var actualRowWidth = gapWidth;
9413            
9414            jQuery.each(row, function(indexInRow, tile){
9415            	var objTile = jQuery(tile);
9416            	var tileIndex = objTile.index();
9417            	var tileWidth = arrWidths[tileIndex];
9418            	var newWidth = Math.round(tileWidth * ratioHeights);
9419            	
9420            	arrRowTileWidths[indexInRow] = newWidth;
9421            	actualRowWidth += newWidth;            	
9422            });
9423        	
9424            //fix images widths by adding or reducing 1 pixel
9425            var diff = actualRowWidth - galleryWidth;
9426            
9427            var newTotal = 0;
9428            jQuery.each(arrRowTileWidths, function(indexInRow, width){
9429            	
9430            	if(diff == 0)            		
9431            		return(false);
9432            	
9433            	if(diff < 0){
9434            		arrRowTileWidths[indexInRow] = width + 1;
9435            		diff++;
9436            	}else{
9437            		arrRowTileWidths[indexInRow] = width - 1;
9438            		diff--;
9439            	}
9440            	
9441            	//if at last item diff stays, add all diff
9442            	if(indexInRow == (arrRowTileWidths.length-1) && diff != 0)
9443            		arrRowTileWidths[indexInRow] -= diff;
9444            });
9445            
9446            arrRowWidths[index] = arrRowTileWidths;
9447		});
9448		
9449		
9450		var objData = {
9451				arrRows: arrRows,
9452				arrRowWidths: arrRowWidths,
9453				arrRowHeights: arrRowHeights,
9454				gap: gap,
9455				totalHeight: totalHeight
9456		};
9457		
9458		return(objData);
9459	}
9460
9461	
9462	/**
9463	 * put justified images
9464	 */
9465	function placeJustified(toShow){
9466		
9467		if(!toShow)
9468			var toShow = false;
9469		
9470		var parentWidth = getParentWidth();
9471
9472		var objData = getJustifiedData();
9473		
9474		//if the width changed after height change (because of scrollbar), recalculate
9475		g_objParent.height(objData.totalHeight);
9476	
9477		var parentWidthAfter = getParentWidth();
9478		if(parentWidthAfter != parentWidth)
9479			objData = getJustifiedData();
9480		
9481		doBeforeTransition();
9482		
9483		var posy = 0;
9484		var totalWidth = 0;		//just count total widht for check / print
9485		jQuery.each(objData.arrRows, function(index, row){
9486        	
9487			var arrRowTileWidths = objData.arrRowWidths[index];
9488			var rowHeight = objData.arrRowHeights[index];
9489			
9490			//resize and place tiles
9491            var posx = 0;
9492            jQuery.each(row, function(indexInRow, tile){
9493            	            	            	
9494            	var objTile = jQuery(tile);
9495            	var tileHeight = rowHeight;
9496            	var tileWidth = arrRowTileWidths[indexInRow];
9497            	
9498            	g_objTileDesign.resizeTile(objTile, tileWidth, tileHeight, g_objTileDesign.resizemode.VISIBLE_ELEMENTS);
9499            	g_functions.placeElement(objTile, posx, posy);
9500            	
9501            	posx += tileWidth;
9502            	
9503            	if(posx > totalWidth)
9504            		totalWidth = posx;
9505            	
9506            	posx += objData.gap;
9507            	
9508            	if(toShow == true)
9509            		jQuery(tile).show();
9510            
9511            });
9512            
9513            posy += (rowHeight + objData.gap);
9514            
9515		});
9516		
9517		doAfterTransition();
9518		
9519	}
9520	
9521	
9522	
9523	/**
9524	 * run justified type gallery
9525	 */
9526	function runJustifiedType(){
9527		
9528		var objImages = jQuery(g_objWrapper).find("img.ug-thumb-image");
9529		var objTiles = g_thumbs.getThumbs();
9530		
9531		g_temp.isAllLoaded = false;
9532		
9533		objTiles.fadeTo(0,0);				
9534		
9535		g_functions.checkImagesLoaded(objImages, function(){
9536			
9537			setTimeout(function(){
9538				placeJustified(true);
9539				objTiles.fadeTo(0,1);
9540				g_gallery.triggerEvent(t.events.TILES_FIRST_PLACED);
9541				setTransition();
9542				
9543				g_objThis.trigger(t.events.ALL_TILES_LOADED);
9544				
9545			});
9546			
9547		}, function(objImage, isError){
9548
9549			objImage = jQuery(objImage);
9550			var objTile = jQuery(objImage).parent();
9551			g_thumbs.triggerImageLoadedEvent(objTile, objImage);
9552		
9553		});
9554				
9555	}
9556	
9557
9558	
9559		
9560    function __________NESTED_TYPE_RELATED_________() {    };
9561    
9562    
9563    /**
9564     * ------------ NESTED TYPE RELATED FUNCTIONS ----------------
9565     */
9566    function runNestedType() {
9567
9568        var objImages = jQuery(g_objWrapper).find("img.ug-thumb-image");
9569        var objTiles = g_thumbs.getThumbs();
9570        
9571        g_temp.isAllLoaded = false;
9572        
9573        objTiles.fadeTo(0, 0);
9574        
9575        g_functions.checkImagesLoaded(objImages, function () {
9576        	
9577        	if(g_gallery.isMobileMode() == true){
9578        		placeTiles(true);
9579        	}
9580        	else
9581        		placeNestedImages(true);
9582            
9583        	g_gallery.triggerEvent(t.events.TILES_FIRST_PLACED);
9584            setTransition();
9585            g_objThis.trigger(t.events.ALL_TILES_LOADED);
9586
9587        }, function (objImage, isError) {
9588
9589            objImage = jQuery(objImage);
9590            var objTile = jQuery(objImage).parent();
9591            g_thumbs.triggerImageLoadedEvent(objTile, objImage);
9592
9593        });
9594
9595    }
9596
9597    
9598    /**
9599     * fill nested vars
9600     */
9601    function fillNestedVars(){
9602
9603    	var galleryWidth = getParentWidth();
9604    	g_nestedWork.galleryWidth = galleryWidth;
9605        
9606        g_arrNestedGridRow = {};
9607    	g_nestedWork.colWidth = g_options.tiles_nested_col_width;
9608    	g_nestedWork.optimalTileWidth = g_options.tiles_nested_optimal_tile_width;
9609    	
9610    	g_nestedWork.currentGap = g_options.tiles_space_between_cols;
9611
9612    	if(g_gallery.isMobileMode() == true)
9613            g_nestedWork.currentGap = g_options.tiles_space_between_cols_mobile;
9614    	
9615        if(g_nestedWork.colWidth == null){
9616			g_nestedWork.colWidth = Math.floor(g_nestedWork.optimalTileWidth/g_nestedWork.nestedOptimalCols);
9617		} else if (g_nestedWork.optimalTileWidth > g_nestedWork.colWidth) {
9618            g_nestedWork.nestedOptimalCols = Math.ceil(g_nestedWork.optimalTileWidth / g_nestedWork.colWidth);
9619        } else {
9620            g_nestedWork.nestedOptimalCols = 1;
9621        }
9622    	
9623    	g_nestedWork.maxColumns = g_functions.getNumItemsInSpace(galleryWidth, g_nestedWork.colWidth, g_nestedWork.currentGap);
9624    	
9625        //fix col width - justify tiles
9626        g_nestedWork.colWidth = g_functions.getItemSizeInSpace(galleryWidth, g_nestedWork.maxColumns, g_nestedWork.currentGap);
9627        
9628        g_nestedWork.gridY = 0;
9629        g_arrNestedItems = []
9630        
9631    	var objTiles = g_thumbs.getThumbs(true);
9632		objTiles.each(function(){
9633			var objTile = jQuery(this);
9634		    var sizes = setNestedSize(objTile);
9635		    g_arrNestedItems.push(sizes);
9636		 });
9637        
9638        if (g_nestedWork.optimalTileWidth > g_nestedWork.colWidth) {
9639            g_nestedWork.nestedOptimalCols = Math.ceil(g_nestedWork.optimalTileWidth / g_nestedWork.colWidth);
9640        } else {
9641            g_nestedWork.nestedOptimalCols = 1;
9642        }
9643        
9644        g_nestedWork.totalWidth = g_nestedWork.maxColumns*(g_nestedWork.colWidth+g_nestedWork.currentGap)-g_nestedWork.currentGap;
9645
9646        switch(g_options.tiles_align){
9647			case "center":
9648			default:
9649				//add x to center point
9650				g_nestedWork.addX = Math.round( (g_nestedWork.galleryWidth - g_nestedWork.totalWidth) / 2 );
9651			break;
9652			case "left":
9653				g_nestedWork.addX = 0;
9654			break;
9655			case "right":
9656				g_nestedWork.addX = g_nestedWork.galleryWidth - g_nestedWork.totalWidth;
9657			break;
9658		}
9659        
9660        
9661        g_nestedWork.maxGridY = 0;
9662    }
9663    
9664    
9665    /**
9666     * place Nested type images
9667     */
9668    function placeNestedImages(toShow){
9669    	
9670    	var parentWidth = getParentWidth();
9671    	
9672    	fillNestedVars();
9673        placeNestedImagesCycle();
9674    	
9675        var totalHeight = g_nestedWork.maxGridY * (g_nestedWork.colWidth + g_nestedWork.currentGap) - g_nestedWork.currentGap;
9676
9677    	//if the width changed after height change (because of scrollbar), recalculate
9678		g_objParent.height(totalHeight);
9679		
9680		var parentWidthAfter = getParentWidth();
9681		
9682		if(parentWidthAfter != parentWidth){
9683    		fillNestedVars();
9684        	placeNestedImagesCycle();
9685        }
9686        
9687        if(g_options.tiles_nested_debug == false)
9688        	drawNestedImages(toShow);
9689
9690    }
9691
9692    
9693    /**
9694     * set Nested size
9695     */
9696    function setNestedSize(objTile){
9697
9698        var dimWidth, dimHeight;
9699        var output = {};
9700        
9701        var colWidth = g_nestedWork.colWidth;
9702        var gapWidth = g_nestedWork.currentGap;
9703        
9704        var objImageSize = g_objTileDesign.getTileImageSize(objTile);
9705        var index = objTile.index();
9706        
9707        var maxDim = Math.ceil(getPresettedRandomByWidth(index)*(g_nestedWork.nestedOptimalCols*1/3) + g_nestedWork.nestedOptimalCols * 2/3);
9708        
9709        var imgWidth = objImageSize.width;
9710        var imgHeight = objImageSize.height;
9711        
9712        var ratio = imgWidth/imgHeight;
9713        
9714        if(imgWidth>imgHeight){
9715            dimWidth = maxDim;
9716            dimHeight = Math.round(dimWidth/ratio);
9717            if(dimHeight == 0){
9718                dimHeight = 1;
9719            }
9720        } else {
9721            dimHeight = maxDim;
9722            dimWidth = Math.round(dimHeight*ratio);
9723            if(dimWidth == 0){
9724                dimWidth = 1;
9725            }
9726        }
9727
9728        output.dimWidth = dimWidth;
9729        output.dimHeight = dimHeight;
9730        output.width = dimWidth * colWidth + gapWidth*(dimWidth-1);
9731        output.height = dimHeight * colWidth + gapWidth*(dimHeight-1);
9732        output.imgWidth =  imgWidth;
9733        output.imgHeight = imgHeight;
9734        output.left = 0;
9735        output.top = 0;
9736        return output;
9737    }
9738
9739    
9740    /**
9741     *  get presetted random [0,1] from int
9742     */
9743    function getPresettedRandomByWidth(index){
9744        return Math.abs(Math.sin(Math.abs(Math.sin(index)*1000)));
9745    }
9746
9747    
9748    /**
9749     * place nested images debug
9750     */
9751    function placeNestedImagesDebug(toShow, placeOne){
9752        
9753    	if(placeOne == false){
9754            for(var i = g_nestedWork.currentItem; i<g_arrNestedItems.length; i++){
9755                placeNestedImage(i, true);
9756            }
9757            g_nestedWork.currentItem = g_arrNestedItems.length-1;
9758        } else {
9759            placeNestedImage(g_nestedWork.currentItem, true);
9760        }
9761        
9762    	for(var i = 0; i<=g_nestedWork.currentItem; i++){
9763            drawNestedImage(i, true);
9764        }
9765
9766        g_nestedWork.currentItem++;
9767    	
9768    }
9769    
9770    
9771    /**
9772     * start cycle of placing imgaes
9773     */
9774    function placeNestedImagesCycle(placeOne){
9775                
9776        if(g_options.tiles_nested_debug == true){
9777
9778        	if(typeof placeOne === 'undefined')
9779                placeOne = true;
9780        	
9781        	placeNestedImagesDebug(true, placeOne);
9782        	
9783        	return(false);
9784        } 
9785                
9786        for(var i = 0; i < g_arrNestedItems.length; i++)
9787                placeNestedImage(i, true);
9788    
9789    }
9790
9791
9792    /**
9793     * place Nested Image
9794     */
9795    function placeNestedImage(tileID, toShow){
9796
9797        if(!toShow)
9798            var toShow = false;
9799                
9800        g_nestedWork.maxColHeight = 0;
9801
9802        var rowsValue = g_functions.getObjectLength(g_arrNestedGridRow);
9803
9804        for(var row = g_nestedWork.gridY; row<=rowsValue+1; row++){
9805            for (var column = 0; column < g_nestedWork.maxColumns; column++) {
9806                if (isGridRowExists(g_nestedWork.gridY) == false || isGridCellTaken(g_nestedWork.gridY, column) == false) {
9807                    var totalFree = getTotalFreeFromPosition(column);
9808                    calculateOptimalStretchAndPosition(tileID, totalFree, column);
9809                                        
9810                    return;
9811                }
9812            }
9813            g_nestedWork.gridY++;
9814        }
9815        
9816    }
9817
9818    
9819    /**
9820     * calculate optimal stretch of tile
9821     */
9822    function calculateOptimalStretchAndPosition(tileID, totalFree, column){
9823
9824        var sizes = jQuery.extend(true, {}, g_arrNestedItems[tileID]);
9825        var currentWidth = sizes.dimWidth;
9826        var placeForNextImage = totalFree - sizes.dimWidth;
9827        var optimalWidth = g_nestedWork.nestedOptimalCols;
9828        var onlyCurrentImage = (totalFree<=sizes.dimWidth || placeForNextImage<=0.33*optimalWidth || totalFree<=optimalWidth);
9829
9830        //Width stretching if needed
9831        if(onlyCurrentImage){	// if free space is smaller than image width - place to this space anyway
9832            resizeToNewWidth(tileID, totalFree);
9833        } else if (placeForNextImage<=optimalWidth){ // if there are place for 2 images
9834            if(optimalWidth>=4){
9835                if(isGridImageAligned(Math.floor(totalFree/2), column) == true){
9836                    resizeToNewWidth(tileID, Math.floor(totalFree/2)+1);
9837                } else {
9838                    resizeToNewWidth(tileID, Math.floor(totalFree/2));
9839                }
9840            } else {
9841                resizeToNewWidth(objImage, totalFree);
9842            }
9843        } else {
9844            if(isGridImageAligned(currentWidth, column) == true){
9845                switch(currentWidth>=optimalWidth){
9846                    case true:
9847                        resizeToNewWidth(tileID, currentWidth-1);
9848                        break
9849                    case false:
9850                        resizeToNewWidth(tileID, currentWidth+1);
9851                        break
9852
9853                }
9854            }
9855        }
9856
9857        //Height stretching if needed
9858        sizes = jQuery.extend(true, {}, g_arrNestedItems[tileID]);
9859        var columnInfo = getGridColumnHeight(tileID, sizes.dimWidth, column); 	// [columnHeight, imagesIDs]
9860
9861        if(g_nestedWork.columnsValueToEnableHeightResize <= columnInfo[0] && g_nestedWork.maxColumns>=2*g_nestedWork.nestedOptimalCols){
9862
9863            var sideHelper = getGridImageVerticalDifference(column, sizes);
9864            var columnSizes = resizeToNewHeight(tileID, sideHelper.newHeight, true);
9865            g_arrNestedItems[tileID].dimHeight = columnSizes.dimHeight;
9866            var columnResizes = redistributeColumnItems(columnInfo, columnSizes.dimWidth, column);
9867            var columnCrosshairs = getColumnCrosshairsCount(columnResizes);
9868            var disableColumnResizes = false;
9869
9870            if(columnCrosshairs >= 2){
9871                disableColumnResizes = true;
9872            }
9873
9874            if(sideHelper.newHeight>=sizes.dimHeight){
9875                sizes = resizeToNewHeight(tileID, sideHelper.newHeight, true);
9876            }
9877            var sideResizes = getSideResizeInfo(sideHelper.idToResize, sideHelper.newHeight, sizes.dimHeight);
9878            sizes.top = g_nestedWork.gridY;
9879            sizes.left = column;
9880            sideResizes.push({"tileID": tileID, "sizes": sizes});
9881
9882            var sideResizesVal = calcResizeRatio(sideResizes);
9883            var columnResizesVal = calcResizeRatio(columnResizes);
9884
9885            if(sideResizesVal<columnResizesVal || disableColumnResizes == true) {
9886                applyResizes(sideResizes);
9887                return;
9888            } else {
9889                applyResizes(columnResizes);
9890                return;
9891            }
9892
9893
9894        }
9895        sizes.left = column;
9896        sizes.top = g_nestedWork.gridY;
9897        g_arrNestedItems[tileID] = sizes;
9898        putImageToGridRow(tileID, sizes, column, g_nestedWork.gridY);
9899        
9900        g_nestedWork.maxGridY = sizes.top + sizes.dimHeight;
9901        
9902    }
9903
9904    /**
9905     * check columns crosshairs
9906     */
9907    function getColumnCrosshairsCount(tilesAndSizes){
9908
9909        var crosshairsCountR = 0;
9910        var crosshairsCountL = 0;
9911
9912        for(var i = 0; i<tilesAndSizes.length-1; i++){
9913
9914            var sizes = tilesAndSizes[i].sizes;
9915            var topItem = -1;
9916            var bottomItem = -1;
9917            if(isGridRowExists(sizes.top+sizes.dimHeight) && g_nestedWork.maxColumns>sizes.left+sizes.dimWidth){
9918                topItem = g_arrNestedGridRow[sizes.top+sizes.dimHeight-1][sizes.left+sizes.dimWidth];
9919                bottomItem = g_arrNestedGridRow[sizes.top+sizes.dimHeight][sizes.left+sizes.dimWidth];
9920            }
9921            if(topItem != bottomItem){
9922                crosshairsCountR++;
9923            }
9924        }
9925
9926        for(var i = 0; i<tilesAndSizes.length-1; i++){
9927
9928            var sizes = tilesAndSizes[i].sizes;
9929            var topItem = -1;
9930            var bottomItem = -1;
9931            if(isGridRowExists(sizes.top+sizes.dimHeight) && sizes.left-1>=0){
9932                topItem = g_arrNestedGridRow[sizes.top+sizes.dimHeight-1][sizes.left-1];
9933                bottomItem = g_arrNestedGridRow[sizes.top+sizes.dimHeight][sizes.left-1];
9934            }
9935            if(topItem != bottomItem){
9936                crosshairsCountL++;
9937            }
9938        }
9939        return Math.max(crosshairsCountL, crosshairsCountR);
9940    }
9941
9942    /**
9943     * get size resize info
9944     */
9945    function getSideResizeInfo(idToResize, newHeight, dimHeight){
9946
9947        var currentTile = g_arrNestedItems[idToResize];
9948        var	tileHeight = currentTile.dimHeight;
9949        var tileWidth = currentTile.dimWidth;
9950        var tileLeft = currentTile.left;
9951        var tileTop = currentTile.top;
9952        var tileDimTop = parseInt(tileTop / (g_nestedWork.colWidth + g_nestedWork.currentGap));
9953        var tileDimLeft = parseInt(tileLeft / (g_nestedWork.colWidth + g_nestedWork.currentGap));
9954        var newSideHeight = tileHeight - newHeight + dimHeight;
9955
9956        var sideSizes = resizeToNewHeight(idToResize, newSideHeight, true);
9957        var output = [];
9958        output.push({"tileID": idToResize, "sizes": sideSizes});
9959        return output;
9960    }
9961
9962    /**
9963     * apply resizes to fix column
9964     */
9965    function applyResizes(resizeTilesAndSizes){
9966
9967        for(var i = 0; i<resizeTilesAndSizes.length; i++){
9968            var sizes = resizeTilesAndSizes[i].sizes;
9969            var tileID = resizeTilesAndSizes[i].tileID;
9970            g_arrNestedItems[tileID]=jQuery.extend(true, {}, sizes);
9971            putImageToGridRow(tileID, sizes, sizes.left, sizes.top);
9972        }
9973
9974    }
9975
9976    /**
9977     * redistribute heights in column
9978     * returns current item sizes
9979     */
9980    function redistributeColumnItems(columnInfo, columnWidth){
9981
9982        var originalHeight = 0;
9983        var columnHeight = 0;
9984        var objTiles = [];
9985        var cordX = 0, cordY = 0;
9986
9987        for(var i = 0; i<columnInfo[1].length; i++){
9988            var tileID = columnInfo[1][i];
9989            var currentTile = g_arrNestedItems[columnInfo[1][i]];
9990            columnHeight += currentTile.dimHeight;
9991            if(i==0){
9992                var sizes = resizeToNewWidth(tileID, columnWidth, true);
9993                originalHeight += sizes.dimHeight;
9994                objTiles.push([columnInfo[1][i], sizes.dimHeight]);
9995                continue;
9996            }
9997            originalHeight += currentTile.dimHeight;
9998            objTiles.push([tileID, currentTile.dimHeight]);
9999        }
10000
10001        cordX = currentTile.left;
10002        cordY = currentTile.top;
10003
10004        var tempHeight = columnHeight;
10005        var output = [];
10006
10007        for(var i = objTiles.length-1; i>=0; i--){
10008            var tileID = objTiles[i][0];
10009            var newHeight;
10010            if(i != 0) {
10011                newHeight = Math.max(Math.round(columnHeight*1/3),Math.floor(objTiles[i][1] * (columnHeight / originalHeight)));
10012                tempHeight = tempHeight - newHeight;
10013                sizes = resizeToNewHeight(tileID, newHeight, true);
10014                sizes.left = cordX;
10015                sizes.top = cordY;
10016                output.push({"tileID": tileID, "sizes": sizes});
10017                cordY += sizes.dimHeight;
10018            } else {
10019                newHeight = tempHeight;
10020                sizes = resizeToNewHeight(tileID, newHeight, true);
10021                sizes.left = cordX;
10022                sizes.top = cordY;
10023                output.push({"tileID": tileID, "sizes": sizes});
10024            }
10025        }
10026        return output;
10027    }
10028
10029    /**
10030     * Calculate num of objects in current column and return they are ID's
10031     */
10032    function getGridColumnHeight(tileID, dimWidth, column){
10033        var tempY = g_nestedWork.gridY-1;
10034        var curImage = 0;
10035        var prevImage = 0;
10036        var columnHeight = 1;
10037        var imagesIDs = [];
10038        var toReturn = [];
10039        imagesIDs.push(tileID);
10040        if(tempY>=0){
10041            prevImage = 0;
10042            while(tempY>=0){
10043                curImage = g_arrNestedGridRow[tempY][column];
10044                if( (typeof g_arrNestedGridRow[tempY][column-1] === 'undefined' || g_arrNestedGridRow[tempY][column-1] != g_arrNestedGridRow[tempY][column])
10045                    &&(typeof g_arrNestedGridRow[tempY][column+dimWidth] === 'undefined' || g_arrNestedGridRow[tempY][column+dimWidth-1] != g_arrNestedGridRow[tempY][column+dimWidth])
10046                    &&(g_arrNestedGridRow[tempY][column]==g_arrNestedGridRow[tempY][column+dimWidth-1])){
10047                    if(prevImage != curImage){
10048                        columnHeight++;
10049                        imagesIDs.push(curImage);
10050                    }
10051                } else {
10052                    toReturn.push(columnHeight);
10053                    toReturn.push(imagesIDs);
10054                    return toReturn;
10055                }
10056                tempY--;
10057                prevImage = curImage;
10058            }
10059            toReturn.push(columnHeight);
10060            toReturn.push(imagesIDs);
10061            return toReturn;
10062        }
10063        return [0, []];
10064    }
10065
10066    /**
10067     * get new height based on left and right difference
10068     */
10069    function getGridImageVerticalDifference(column, sizes){
10070        var newHeightR = 0;
10071        var newHeightL = 0;
10072        var dimWidth = sizes.dimWidth;
10073        var dimHeight = sizes.dimHeight;
10074        var leftID = 0;
10075        var rightID = 0;
10076        var array = jQuery.map(g_arrNestedGridRow, function(value, index) {
10077            return [value];
10078        });
10079
10080        if(typeof array[g_nestedWork.gridY] === 'undefined' || typeof array[g_nestedWork.gridY][column-1]=== 'undefined'){
10081            newHeightL = 0;
10082        } else {
10083            var tempY=0;
10084            while(true){
10085                if(typeof g_arrNestedGridRow[g_nestedWork.gridY+tempY] !== 'undefined' && g_arrNestedGridRow[g_nestedWork.gridY+tempY][column-1] != -1 ){
10086                    leftID = g_arrNestedGridRow[g_nestedWork.gridY+tempY][column-2];
10087                    tempY++;
10088                    newHeightL++;
10089                } else {
10090                    break;
10091                }
10092            }
10093        }
10094
10095        if(typeof array[g_nestedWork.gridY] === 'undefined' || typeof array[g_nestedWork.gridY][column+dimWidth]=== 'undefined'){
10096            newHeightR = 0;
10097        } else {
10098            tempY=0;
10099            while(true){
10100                if(typeof g_arrNestedGridRow[g_nestedWork.gridY+tempY] !== 'undefined' && g_arrNestedGridRow[g_nestedWork.gridY+tempY][column+dimWidth] != -1 ){
10101                    rightID = g_arrNestedGridRow[g_nestedWork.gridY+tempY][column+dimWidth+1];
10102                    tempY++;
10103                    newHeightR++;
10104                } else {
10105                    break;
10106                }
10107            }
10108        }
10109
10110        var newHeight = 0;
10111        var idToResize = 0;
10112        if(Math.abs(dimHeight - newHeightL) < Math.abs(dimHeight - newHeightR) && newHeightL != 0) {
10113            newHeight = newHeightL;
10114            idToResize = leftID;
10115        } else if (newHeightR !=0) {
10116            newHeight = newHeightR;
10117            idToResize = rightID;
10118        } else {
10119            newHeight = dimHeight; //malo li
10120        }
10121
10122        var output = {"newHeight": newHeight, "idToResize": idToResize};
10123
10124        return output;
10125    }
10126
10127    /**
10128     * resize to new Dim width
10129     */
10130    function resizeToNewWidth(tileID, newDimWidth, toReturn) {
10131        if(!toReturn){
10132            toReturn = false;
10133        }
10134        
10135        var colWidth = g_nestedWork.colWidth;
10136        var gapWidth = g_nestedWork.currentGap;
10137        var currentTile = g_arrNestedItems[tileID];
10138        var imgWidth = currentTile.imgWidth;
10139        var imgHeight = currentTile.imgHeight;
10140        var ratio = imgWidth / imgHeight;
10141        dimWidth = newDimWidth;
10142        dimHeight = Math.round(dimWidth / ratio);
10143        if(toReturn == true){
10144            var sizes = jQuery.extend(true, {}, currentTile);
10145            sizes.dimWidth = dimWidth;
10146            sizes.dimHeight = dimHeight;
10147            sizes.width = dimWidth * colWidth + gapWidth * (dimWidth - 1);
10148            sizes.height = dimHeight * colWidth + gapWidth * (dimHeight - 1);
10149            return sizes;
10150        }
10151        currentTile.dimWidth = dimWidth;
10152        currentTile.dimHeight = dimHeight;
10153        currentTile.width = dimWidth * colWidth + gapWidth * (dimWidth - 1);
10154        currentTile.height = dimHeight * colWidth + gapWidth * (dimHeight - 1);
10155    }
10156
10157    /**
10158     * resize to new height without width changing
10159     */
10160    function resizeToNewHeight(tileID, newDimHeight, toReturn) {
10161
10162        if(!toReturn){
10163            toReturn = false;
10164        }
10165
10166        var currentTile = g_arrNestedItems[tileID];
10167        var dimWidth = currentTile.dimWidth;
10168        var colWidth = g_nestedWork.colWidth;
10169        var gapWidth = g_nestedWork.currentGap;
10170
10171        if(toReturn == true){
10172            var sizes = jQuery.extend(true, {}, currentTile);
10173
10174            sizes.dimHeight = newDimHeight;
10175            sizes.width = dimWidth * colWidth + gapWidth * (dimWidth - 1);
10176            sizes.height = newDimHeight * colWidth + gapWidth * (newDimHeight - 1);
10177            
10178            return sizes;
10179        }
10180
10181        currentTile.dimHeight = newDimHeight;
10182        currentTile.width = dimWidth * colWidth + gapWidth * (dimWidth - 1);
10183        currentTile.height = newDimHeight * colWidth + gapWidth * (newDimHeight - 1);
10184    }
10185
10186    /**
10187     * calc resize koef
10188     */
10189    function calcResizeRatio(objTilesAndSizes){
10190        var tempResizes = 0;
10191        var tempNum = 0;
10192
10193        for(var i = 0; i<objTilesAndSizes.length; i++){
10194            var sizes = g_arrNestedItems[objTilesAndSizes[i].tileID];
10195            if((sizes.dimHeight != 0) && (sizes.height != 0)){
10196                resizeVal = (sizes.dimWidth/sizes.dimHeight)/(sizes.imgWidth/sizes.imgHeight);
10197            } else {
10198                return;
10199            }
10200            if(resizeVal < 1){
10201                resizeVal = 1/resizeVal;
10202            }
10203            tempResizes += resizeVal;
10204            tempNum++;
10205        }
10206        return tempResizes/tempNum;
10207    }
10208
10209    /**
10210     * check for column break
10211     */
10212    function isGridImageAligned(dimWidth, column){
10213        var y = g_nestedWork.gridY-1;
10214        if(y<=0 || isGridRowExists(y) == false){
10215            return false;
10216        }
10217        if(g_arrNestedGridRow[y][column+dimWidth-1]!=g_arrNestedGridRow[y][column+dimWidth]) {
10218            return true;
10219        }
10220
10221        return false;
10222    }
10223
10224    /**
10225     * get free line length in GridRow
10226     */
10227    function getTotalFreeFromPosition(column){
10228        var x = column;
10229        var totalFree = 0;
10230        if(isGridRowExists(g_nestedWork.gridY) == true){
10231            while(isGridCellTaken(g_nestedWork.gridY, x) == false){
10232                totalFree ++;
10233                x++;
10234            }
10235        } else {
10236            totalFree = g_nestedWork.maxColumns;
10237        }
10238        return totalFree;
10239    }
10240
10241    /**
10242     * is nestedGridRow row exists
10243     */
10244    function isGridRowExists(y){
10245        if(typeof g_arrNestedGridRow[y] === 'undefined'){
10246            return false;
10247        }
10248        return true;
10249    }
10250
10251    
10252    /**
10253     * put image to grid row
10254     */
10255    function putImageToGridRow(id, sizes, gridX, gridY){
10256        
10257    	for (var y = 0; y < sizes.dimHeight; y++) {
10258            for (var x = 0; x < sizes.dimWidth; x++) {
10259                if (isGridRowExists(gridY+y) == 0) {
10260                    addGridRow(gridY+y);
10261                }
10262                
10263                setGridCellValue(gridY+y, gridX+x, id);
10264            }
10265        }
10266    }
10267
10268    /**
10269     * add grid with Y index
10270     */
10271    function addGridRow(y){
10272        g_arrNestedGridRow[y] = new Object;
10273        for (var t = 0; t < g_nestedWork.maxColumns; t++) {
10274            g_arrNestedGridRow[y][t] = -1;
10275        }
10276    }
10277
10278    /**
10279     * isGridRowCellTaken
10280     */
10281    function isGridCellTaken(y,x){
10282        return (g_arrNestedGridRow[y][x] != -1);
10283    }
10284
10285    /**
10286     * set nestedGridRow cell value
10287     */
10288    function setGridCellValue(y,x,value){
10289        g_arrNestedGridRow[y][x]=value;
10290    }
10291
10292
10293    /**
10294     * draw nested images
10295     */
10296    function drawNestedImages(toShow){
10297    	
10298        if(!toShow)
10299            var toShow = false;
10300        
10301        doBeforeTransition();
10302        
10303        for(var i = 0; i<g_arrNestedItems.length; i++){
10304            drawNestedImage(i, toShow);
10305        }
10306
10307        g_objParent.height(g_nestedWork.maxColHeight);
10308        
10309        doAfterTransition();
10310    }
10311
10312    
10313    /**
10314     * draw nested image
10315     */
10316    function drawNestedImage(i, toShow){
10317    	
10318        var objTile = g_thumbs.getThumbByIndex(i);
10319
10320        var sizes = g_arrNestedItems[i];
10321        var newY = sizes.top * (g_nestedWork.colWidth + g_nestedWork.currentGap);
10322        var newX = g_nestedWork.addX + sizes.left * (g_nestedWork.colWidth + g_nestedWork.currentGap);
10323        
10324        g_objTileDesign.resizeTile(objTile, sizes.width, sizes.height, g_objTileDesign.resizemode.VISIBLE_ELEMENTS);
10325        
10326        g_functions.placeElement(objTile, newX, newY);
10327                
10328        if(newY + sizes.height > g_nestedWork.maxColHeight){
10329            g_nestedWork.maxColHeight = newY + sizes.height;
10330        };
10331        
10332        if(toShow == true){
10333            objTile.fadeTo(0, 1);
10334        }
10335        
10336    }
10337	
10338	
10339	function __________COMMON_AND_EVENTS_______(){};
10340	
10341	
10342	/**
10343	 * on resize event
10344	 */
10345	function onResize(){
10346		
10347		if(g_temp.isFirstTimeRun == true)
10348			return(true);
10349		
10350		if(g_temp.isAllLoaded == false)
10351			return(false);
10352		
10353		switch(g_options.tiles_type){
10354			case "columns":
10355				placeTiles(false);
10356			break;
10357			case "justified":
10358				placeJustified(false);
10359			break;
10360            case "nested":
10361            	
10362            	var isMobileMode = g_gallery.isMobileMode();
10363            	if(isMobileMode == true){
10364            		placeTiles(false);
10365            	}
10366            	else
10367            		placeNestedImages(false);
10368            
10369            break;
10370		}
10371		
10372	}
10373
10374	
10375	/**
10376	 * init panel events
10377	 */
10378	function initEvents(){
10379		
10380		g_objThis.on(t.events.ALL_TILES_LOADED, function(){
10381			
10382			g_temp.isAllLoaded = true;
10383			
10384		});
10385		
10386		g_objGallery.on(g_gallery.events.SIZE_CHANGE, onResize);
10387		
10388		g_objGallery.on(t.events.TILES_FIRST_PLACED,function(){
10389			g_temp.isFirstPlaced = false;
10390		});
10391		
10392		g_objTileDesign.initEvents();
10393				
10394	}
10395
10396	
10397	/**
10398	 * run the gallery after init and set html
10399	 */
10400	function run(){
10401				
10402		//show tiles
10403		g_objWrapper.children(".ug-tile").show();
10404
10405		if(g_temp.isFirstTimeRun == true){
10406			initEvents();
10407		}
10408		
10409		g_objTileDesign.run();
10410		
10411		switch(g_options.tiles_type){
10412			default:
10413			case "columns":
10414				runColumnsType();
10415			break;
10416			case "justified":
10417				runJustifiedType();
10418			break;
10419			case "nested":
10420				runNestedType();
10421			break;
10422		}
10423		
10424		
10425		g_temp.isFirstTimeRun = false;
10426	}
10427	
10428	
10429	/**
10430	 * destroy the events
10431	 */
10432	this.destroy = function(){
10433		
10434		g_objGallery.off(g_gallery.events.SIZE_CHANGE);
10435		g_objTileDesign.destroy();
10436		g_objGallery.off(t.events.TILES_FIRST_PLACED);
10437		
10438	}
10439	
10440		
10441	
10442	/**
10443	 * init function for avia controls
10444	 */
10445	this.init = function(gallery, customOptions){
10446		
10447		init(gallery, customOptions);
10448	}
10449
10450	
10451	/**
10452	 * set html
10453	 */
10454	this.setHtml = function(objParent){
10455		setHtml(objParent);
10456	}
10457	
10458	/**
10459	 * get tile design object
10460	 */
10461	this.getObjTileDesign = function(){
10462		return(g_objTileDesign);
10463	}
10464	
10465	/**
10466	 * set html and properties
10467	 */	
10468	this.run = function(){
10469		run();
10470	}
10471	
10472	
10473	/**
10474	 * run the new items
10475	 */
10476	this.runNewItems = function(){
10477		
10478		if(!g_objParent)
10479			throw new Error("Can't run new items - parent not set");
10480		
10481		g_objTileDesign.setHtml(g_objParent, true);
10482		
10483		g_objTileDesign.run(true);
10484		
10485		
10486		switch(g_options.tiles_type){
10487			case "columns":
10488				
10489				runColumnsType();
10490				
10491			break;
10492			default:
10493			case "justified":
10494			case "nested":
10495				throw new Error("Tiles type: "+g_options.tiles_type+" not support load more yet");
10496			break;
10497		}
10498		
10499	}
10500	
10501}
10502
10503
10504
10505/**
10506 * tiles design class
10507 */
10508function UGTileDesign(){
10509	
10510	var t = this, g_objThis = jQuery(this);	
10511	var g_gallery = new UniteGalleryMain(), g_objGallery;
10512	var g_functions = new UGFunctions(), g_objParentWrapper, g_objWrapper;
10513	var g_thumbs = new UGThumbsGeneral(), g_items;
10514	
10515	this.resizemode = {			//modes constants for resize tile
10516		FULL: "full",
10517		WRAPPER_ONLY: "wrapper_only",
10518		VISIBLE_ELEMENTS: "visible_elements"
10519	};
10520	
10521	this.sizeby = {				//sizeby option constants
10522		GLOBAL_RATIO: "global_ratio",
10523		TILE_RATIO: "tile_ratio",
10524		IMAGE_RATIO: "image_ratio",
10525		CUSTOM: "custom"
10526	};
10527	
10528	this.events = {
10529			TILE_CLICK: "tile_click"
10530	};
10531	
10532	var g_options = {
10533						
10534			tile_width: 250,						//in case of fixed size: tile width
10535			tile_height: 200,						//in case of fixed size: tile height
10536			tile_size_by:t.sizeby.IMAGE_RATIO,		//image ratio, tile ratio , global_ratio - decide by what parameter resize the tile
10537			tile_visible_before_image:false,		//tile visible before image load
10538			
10539			tile_enable_background:true,			//enable backgruond of the tile
10540			tile_background_color: "#F0F0F0",		//tile background color
10541			
10542			tile_enable_border:false,				//enable border of the tile
10543			tile_border_width:3,					//tile border width
10544			tile_border_color:"#F0F0F0",			//tile border color
10545			tile_border_radius:0,					//tile border radius (applied to border only, not to outline)
10546			
10547			tile_enable_outline: false,				//enable outline of the tile (works only together with the border)
10548			tile_outline_color: "#8B8B8B",			//tile outline color
10549			
10550			tile_enable_shadow:false,				//enable shadow of the tile
10551			tile_shadow_h:1,						//position of horizontal shadow
10552			tile_shadow_v:1,						//position of vertical shadow
10553			tile_shadow_blur:3,						//shadow blur
10554			tile_shadow_spread:2,					//shadow spread
10555			tile_shadow_color:"#8B8B8B",			//shadow color
10556			
10557			tile_enable_action:	true,				//enable tile action on click like lightbox
10558			tile_as_link: false,					//act the tile as link, no lightbox will appear
10559			tile_link_newpage: true,				//open the tile link in new page
10560
10561			tile_enable_overlay: true,				//enable tile color overlay (on mouseover)
10562			tile_overlay_opacity: 0.4,				//tile overlay opacity
10563			tile_overlay_color: "#000000",			//tile overlay color
10564			
10565			tile_enable_icons: true,				//enable icons in mouseover mode
10566			tile_show_link_icon: false,				//show link icon (if the tile has a link). In case of tile_as_link this option not enabled
10567			tile_videoplay_icon_always_on: 'never',	//'always', 'never', 'mobile_only', 'desktop_only' always show video play icon
10568			tile_space_between_icons: 26,			//initial space between icons, (on small tiles it may change)
10569			
10570			tile_enable_image_effect:false,			//enable tile image effect
10571			tile_image_effect_type: "bw",			//bw, blur, sepia - tile effect type
10572			tile_image_effect_reverse: false,		//reverce the image, set only on mouseover state
10573			
10574			tile_enable_textpanel: false,			 //enable textpanel
10575			tile_textpanel_source: "title",			 //title,desc,desc_title,title_and_desc. source of the textpanel. desc_title - if description empty, put title
10576			tile_textpanel_always_on: false,		 //textpanel always visible - for inside type
10577			tile_textpanel_appear_type: "slide",	 //slide, fade - appear type of the textpanel on mouseover
10578			tile_textpanel_position:"inside_bottom", //inside_bottom, inside_top, inside_center, top, bottom the position of the textpanel
10579			tile_textpanel_offset:0					 //vertical offset of the textpanel
10580	};
10581	
10582	
10583	var g_defaults = {
10584			thumb_color_overlay_effect: true,
10585			thumb_overlay_reverse: true,
10586			thumb_image_overlay_effect: false,
10587			tile_textpanel_enable_description: false,
10588			tile_textpanel_bg_opacity: 0.6,
10589			tile_textpanel_padding_top:8,
10590			tile_textpanel_padding_bottom: 8
10591	};
10592	
10593	var g_temp = {
10594		ratioByHeight:0,
10595		ratioByWidth:0,
10596		eventSizeChange: "thumb_size_change",
10597		funcCustomTileHtml: null,
10598		funcCustomPositionElements: null,
10599		funcParentApproveClick: null,
10600		isSaparateIcons: false,
10601		tileInnerReduce: 0,		//how much reduce from the tile inner elements from border mostly
10602		isTextpanelOutside: false,	//is the textpanel is out of tile image border
10603		hasImageContainer:false,
10604		isVideoplayIconAlwaysOn:false,
10605		isTextPanelHidden:false
10606	};
10607	
10608	
10609	/**
10610	 * init the tile object
10611	 */
10612	function init(gallery, customOptions){
10613		
10614		g_gallery = gallery;
10615		
10616		g_objGallery = jQuery(gallery);		
10617		
10618		var objects = g_gallery.getObjects();
10619		g_objWrapper = objects.g_objWrapper;
10620		
10621		g_items = g_gallery.getArrItems();
10622				
10623		g_options = jQuery.extend(g_options, g_defaults);
10624		
10625		g_options = jQuery.extend(g_options, customOptions);
10626				
10627		modifyOptions();
10628				
10629		g_thumbs.init(gallery, g_options);	
10630		
10631		var objCustomOptions = {allow_onresize:false};
10632		
10633		var customThumbsAdd = ["overlay"];
10634		
10635		if(g_temp.funcCustomTileHtml)
10636			customThumbsAdd = [];
10637		
10638		g_thumbs.setCustomThumbs(setHtmlThumb, customThumbsAdd, objCustomOptions);
10639		
10640		//get thumb default options too:
10641		var thumbOptions = g_thumbs.getOptions();
10642		g_options = jQuery.extend(g_options, thumbOptions);
10643		
10644		//set ratios of fixed mode
10645		g_temp.ratioByWidth = g_options.tile_width / g_options.tile_height;
10646		g_temp.ratioByHeight = g_options.tile_height / g_options.tile_width;
10647		
10648		
10649		//set if tile has image container
10650		if(g_options.tile_size_by == t.sizeby.GLOBAL_RATIO && g_temp.isTextpanelOutside)
10651			g_temp.hasImageContainer = true;
10652		
10653	}
10654	
10655	
10656	/**
10657	 * set thumb and textpanel options according tile options
10658	 */
10659	function modifyOptions(){
10660
10661		//set overlay related options
10662		if(g_options.tile_enable_overlay == true){
10663			
10664			g_options.thumb_overlay_opacity = g_options.tile_overlay_opacity;
10665			g_options.thumb_overlay_color = g_options.tile_overlay_color;
10666		
10667		}else if(g_options.tile_enable_icons == false){		//if nothing on overlay - turn it off
10668			g_options.thumb_color_overlay_effect = false;		
10669		}else{											//if icons enabled - make it transparent
10670			g_options.thumb_overlay_opacity = 0;
10671		}
10672		
10673		//set item as link
10674		if(g_options.tile_as_link){
10675			g_options.thumb_wrapper_as_link = true;
10676			g_options.thumb_link_newpage = g_options.tile_link_newpage;
10677		}
10678		
10679		//outline cannot appear without border
10680		if(g_options.tile_enable_outline == true && g_options.tile_enable_border == false)
10681			g_options.tile_enable_outline = false;
10682		
10683		//set inner reduce value - in case of the border
10684		g_temp.tileInnerReduce = 0;
10685		if(g_options.tile_enable_border){
10686			g_temp.tileInnerReduce = g_options.tile_border_width * 2;
10687			g_thumbs.setThumbInnerReduce(g_temp.tileInnerReduce);
10688		}
10689
10690		//check if saparate icons
10691		g_temp.isSaparateIcons = !g_functions.isRgbaSupported();
10692		
10693		//set if the textpanel is enabled and outside
10694		if(g_options.tile_enable_textpanel == true){
10695			
10696			//optimize for touch device
10697			switch(g_options.tile_textpanel_position){
10698				case "top":
10699					g_options.tile_textpanel_align = "top";
10700				case "bottom":
10701					g_temp.isTextpanelOutside = true;
10702					g_options.tile_textpanel_always_on = true;
10703					g_options.tile_textpanel_offset = 0;
10704				break;
10705				case "inside_top":
10706					g_options.tile_textpanel_align = "top";
10707				break;
10708				case "middle":
10709					g_options.tile_textpanel_align = "middle";
10710					g_options.tile_textpanel_appear_type = "fade";
10711				break;
10712			}
10713			
10714			//if text panel oppearing with the overlay, icons should be saparated
10715			if(g_options.tile_textpanel_always_on == false)
10716				g_temp.isSaparateIcons = true;
10717			
10718		}
10719		
10720		
10721		//if the textpanel offset is not from the border, it's always fade.
10722		if(g_options.tile_textpanel_offset != 0){
10723			g_options.tile_textpanel_appear_type = "fade";
10724			g_options.tile_textpanel_margin = g_options.tile_textpanel_offset;
10725		}
10726		
10727		//enable description if needed
10728		if(g_options.tile_textpanel_source == "title_and_desc"){
10729			g_options.tile_textpanel_enable_description = true;
10730			g_options.tile_textpanel_desc_style_as_title = true;
10731		}
10732		
10733	}
10734	
10735
10736	/**
10737	 * set options before render
10738	 */
10739	function modifyOptionsBeforeRender(){
10740		
10741		var isMobile = g_gallery.isMobileMode();
10742		
10743		//set text panel show / hide
10744		
10745		g_temp.isTextPanelHidden = false;
10746		if(isMobile == true && g_options.tile_textpanel_always_on == false)
10747			g_temp.isTextPanelHidden = true;
10748		
10749		
10750		//set video icon always on true / false
10751		
10752		g_temp.isVideoplayIconAlwaysOn = g_options.tile_videoplay_icon_always_on;
10753		
10754		switch(g_options.tile_videoplay_icon_always_on){
10755			case "always":
10756				g_temp.isVideoplayIconAlwaysOn = true;
10757			break;
10758			case "never":
10759				g_temp.isVideoplayIconAlwaysOn = false;
10760			break;
10761			case "mobile_only":
10762				g_temp.isVideoplayIconAlwaysOn = (isMobile == true)?true:false;
10763			break;
10764			case "desktop_only":
10765				g_temp.isVideoplayIconAlwaysOn = (isMobile == false)?true:false;
10766			break;
10767		}
10768		
10769		
10770	}
10771
10772	
10773	/**
10774	 * set thumb html
10775	 */
10776	function setHtmlThumb(objThumbWrapper, objItem){
10777		
10778		objThumbWrapper.addClass("ug-tile");
10779		
10780		if(g_temp.funcCustomTileHtml){
10781			g_temp.funcCustomTileHtml(objThumbWrapper, objItem);
10782			return(false);
10783		}
10784		
10785		var html = "";
10786			
10787		//add image container
10788		if(g_temp.hasImageContainer == true){
10789			html += "<div class='ug-image-container ug-trans-enabled'>";
10790		}
10791		
10792		//add thumb image:
10793		var classImage = "ug-thumb-image";
10794
10795		if(g_options.tile_enable_image_effect == false || g_options.tile_image_effect_reverse == true)
10796			classImage += " ug-trans-enabled";
10797		
10798		var imageAlt = g_functions.stripTags(objItem.title);
10799		imageAlt = g_functions.htmlentitles(imageAlt);
10800		
10801		html += "<img src=\""+g_functions.escapeDoubleSlash(objItem.urlThumb)+"\" alt='"+imageAlt+"' class='"+classImage+"'>";
10802
10803		if(g_temp.hasImageContainer == true){
10804			html += "</div>";
10805		}	
10806		
10807		objThumbWrapper.append(html);
10808		
10809		
10810		if(g_options.tile_size_by == t.sizeby.GLOBAL_RATIO){
10811			objThumbWrapper.fadeTo(0,0);		//turn on in thumbsGeneral
10812		}
10813		
10814		//---- set thumb styles ---- 
10815		
10816		//set border:
10817		var objCss = {};
10818		
10819		if(g_options.tile_enable_background == true){
10820			objCss["background-color"] = g_options.tile_background_color;
10821		}
10822		
10823		if(g_options.tile_enable_border == true){
10824			objCss["border-width"] = g_options.tile_border_width+"px";
10825			objCss["border-style"] = "solid";
10826			objCss["border-color"] = g_options.tile_border_color;
10827			
10828			if(g_options.tile_border_radius)
10829				objCss["border-radius"] = g_options.tile_border_radius+"px";
10830		}
10831		
10832		//set outline:
10833		if(g_options.tile_enable_outline == true){
10834			objCss["outline"] = "1px solid " + g_options.tile_outline_color;
10835		}
10836		
10837		//set shadow
10838		if(g_options.tile_enable_shadow == true){
10839			var htmlShadow = g_options.tile_shadow_h+"px ";
10840			htmlShadow += g_options.tile_shadow_v+"px ";
10841			htmlShadow += g_options.tile_shadow_blur+"px ";
10842			htmlShadow += g_options.tile_shadow_spread+"px ";
10843			htmlShadow += g_options.tile_shadow_color;
10844			
10845			objCss["box-shadow"] = htmlShadow;
10846		}
10847		
10848		objThumbWrapper.css(objCss);
10849		
10850		
10851		//----- add icons
10852		
10853		var htmlAdd = "";
10854		
10855		if(g_options.tile_enable_icons){
10856			
10857			//add zoom icon
10858			if(g_options.tile_as_link == false && g_options.tile_enable_action == true){
10859				var iconPlayClass = "ug-button-play ug-icon-zoom";
10860				if(objItem.type != "image")
10861					iconPlayClass = "ug-button-play ug-icon-play";
10862				
10863				htmlAdd += "<div class='ug-tile-icon " + iconPlayClass + "' style='display:none'></div>";
10864			}
10865			
10866			//add link icon
10867			if(objItem.link && g_options.tile_show_link_icon == true || g_options.tile_as_link == true){
10868				
10869				if(g_options.tile_as_link == false){
10870					var linkTarget = "";
10871					if(g_options.tile_link_newpage == true)
10872						linkTarget = " target='_blank'";
10873					
10874					htmlAdd += "<a href='"+objItem.link+"'"+linkTarget+" class='ug-tile-icon ug-icon-link'></a>";					
10875				}else{
10876					htmlAdd += "<div class='ug-tile-icon ug-icon-link' style='display:none'></div>";					
10877				}
10878				
10879			}
10880		
10881		var toSaparateIcon = g_temp.isSaparateIcons;
10882		if(toSaparateIcon == false && objItem.type != "image" && g_temp.isVideoplayIconAlwaysOn == true)
10883			toSaparateIcon = true;
10884		
10885		if(toSaparateIcon)		//put the icons on the thumb
10886			var objOverlay = objThumbWrapper;
10887		else
10888			var objOverlay = objThumbWrapper.children(".ug-thumb-overlay");
10889		
10890		objOverlay.append(htmlAdd);		
10891		
10892		var objButtonZoom = objOverlay.children("." + iconPlayClass);
10893		
10894		if(objButtonZoom.length == 0)
10895			objButtonZoom = null;
10896		else
10897			objButtonZoom.hide();
10898		
10899		var objButtonLink = objOverlay.children(".ug-icon-link");
10900		
10901		if(objButtonLink.length == 0)
10902			objButtonLink = null;
10903		else
10904			objButtonLink.hide();
10905		
10906		//if only zoom icon, make the tile clickable for lightbox open
10907		if(!objButtonLink && g_options.tile_enable_action == true)
10908			objThumbWrapper.addClass("ug-tile-clickable");
10909		
10910		}  //if icons enabled
10911		else{		//if the icons don't enabled, set the tile clickable
10912			
10913			if(g_options.tile_enable_action == true)
10914				objThumbWrapper.addClass("ug-tile-clickable");
10915		
10916		}
10917		
10918		//add image overlay
10919		if(g_options.tile_enable_image_effect == true){
10920			
10921			var imageEffectClassAdd = "";
10922			if(g_options.tile_image_effect_reverse == false)
10923				imageEffectClassAdd = " ug-trans-enabled";
10924			
10925			var imageOverlayHtml = "<div class='ug-tile-image-overlay"+imageEffectClassAdd+"' >";
10926			var imageEffectClass = " ug-"+g_options.tile_image_effect_type+"-effect";
10927			
10928			imageOverlayHtml += "<img src=\""+g_functions.escapeDoubleSlash(objItem.urlThumb)+"\" alt='"+objItem.title+"' class='"+imageEffectClass + imageEffectClassAdd+"'>";
10929			imageOverlayHtml += "</div>";
10930			
10931			objThumbWrapper.append(imageOverlayHtml);
10932
10933			//hide the image overlay if reversed
10934			if(g_options.tile_image_effect_reverse == true){
10935				objThumbWrapper.children(".ug-tile-image-overlay").fadeTo(0,0);
10936			}
10937			
10938		}
10939		
10940		
10941		//add text panel
10942		if(g_options.tile_enable_textpanel == true){
10943			
10944			var objTextPanel = new UGTextPanel();			 
10945			objTextPanel.init(g_gallery, g_options, "tile");
10946			
10947			//set transition class
10948			var textpanelAddClass = "";
10949			if(g_options.tile_textpanel_always_on == true || g_temp.isTextpanelOutside == true)
10950				textpanelAddClass = "ug-trans-enabled";
10951			
10952			objTextPanel.appendHTML(objThumbWrapper, textpanelAddClass);
10953			
10954			var panelTitle = objItem.title;
10955			var panelDesc = "";
10956			
10957			switch(g_options.tile_textpanel_source){
10958				case "desc":
10959				case "description":
10960					panelTitle = objItem.description;
10961				break;
10962				case "desc_title":
10963					if(objItem.description != "")
10964						panelTitle = objItem.description;
10965				break;
10966				case "title_and_desc":
10967					panelTitle = objItem.title;
10968					panelDesc = objItem.description;
10969				break;
10970			}
10971			
10972			objTextPanel.setTextPlain(panelTitle, panelDesc);
10973			
10974			if(g_options.tile_textpanel_always_on == false)
10975				objTextPanel.getElement().fadeTo(0,0);
10976			
10977			objThumbWrapper.data("objTextPanel", objTextPanel);
10978
10979			//if textpanel always on, it has to be under the overlay
10980			if(g_options.tile_textpanel_always_on == true){
10981				var textPanelElement = getTextPanelElement(objThumbWrapper);
10982				textPanelElement.css("z-index",2);
10983			}
10984			
10985			//if text panel is outside, clone textpanel
10986			if(g_temp.isTextpanelOutside == true){
10987				
10988				var htmlClone = "<div class='ug-tile-cloneswrapper'></div>";
10989				objThumbWrapper.append(htmlClone);
10990				var objCloneWrapper = objThumbWrapper.children(".ug-tile-cloneswrapper");
10991				
10992				var objTextPanelClone = new UGTextPanel(); 
10993				objTextPanelClone.init(g_gallery, g_options, "tile");				
10994				objTextPanelClone.appendHTML(objCloneWrapper);
10995				objTextPanelClone.setTextPlain(panelTitle, panelDesc);
10996				objThumbWrapper.data("objTextPanelClone", objTextPanelClone);
10997			}
10998			
10999		}
11000		
11001		//add additional html
11002		if(objItem.addHtml !== null)
11003			objThumbWrapper.append(objItem.addHtml);
11004		
11005	}
11006	
11007	
11008	/**
11009	 * load tile image, place the image on load
11010	 */
11011	this.loadTileImage = function(objTile){
11012		
11013		var objImage = t.getTileImage(objTile);
11014			
11015		g_functions.checkImagesLoaded(objImage, null, function(objImage,isError){
11016			onPlaceImage(null, objTile, jQuery(objImage));
11017		});
11018		
11019	}
11020	
11021	function _________________GETTERS________________(){};
11022	
11023	
11024	
11025	/**
11026	 * get image overlay
11027	 */
11028	function getTileOverlayImage(objTile){
11029		var objOverlayImage = objTile.children(".ug-tile-image-overlay");
11030		return(objOverlayImage);
11031	}
11032	
11033	/**
11034	 * get tile color overlay
11035	 */
11036	function getTileOverlay(objTile){
11037		var objOverlay = objTile.children(".ug-thumb-overlay");
11038		return(objOverlay);		
11039	}
11040	
11041	
11042	/**
11043	 * get image container
11044	 */
11045	function getTileImageContainer(objTile){
11046		if(g_temp.hasImageContainer == false)
11047			return(null);
11048		
11049		var objImageContainer = objTile.children(".ug-image-container");
11050		
11051		return(objImageContainer);
11052	}
11053	
11054	
11055	/**
11056	 * get image effect
11057	 */
11058	function getTileImageEffect(objTile){		
11059		var objImageEffect = objTile.find(".ug-tile-image-overlay img");			
11060		return(objImageEffect);
11061	}
11062	
11063	
11064	/**
11065	 * get text panel
11066	 */
11067	function getTextPanel(objTile){
11068		var objTextPanel = objTile.data("objTextPanel");
11069		
11070		return(objTextPanel);
11071	}
11072	
11073	
11074	/**
11075	 * get cloned text panel
11076	 */
11077	function getTextPanelClone(objTile){
11078		var objTextPanelClone = objTile.data("objTextPanelClone");
11079		
11080		return(objTextPanelClone);
11081		
11082	}
11083	
11084	
11085	/**
11086	 * get text panel element from the tile
11087	 */
11088	function getTextPanelElement(objTile){
11089		var objTextPanel = objTile.children(".ug-textpanel");
11090		
11091		return(objTextPanel);
11092	}
11093	
11094	
11095	/**
11096	 * get text panel element cloned
11097	 */
11098	function getTextPanelCloneElement(objTile){
11099		var objTextPanel = objTile.find(".ug-tile-cloneswrapper .ug-textpanel");
11100		
11101		if(objTextPanel.length == 0)
11102			throw new Error("text panel cloned element not found");
11103		
11104		return(objTextPanel);
11105		
11106	}
11107	
11108	
11109	/**
11110	 * get text panel height
11111	 */
11112	function getTextPanelHeight(objTile){
11113		
11114		if(g_temp.isTextpanelOutside == true)
11115			var objTextPanel = getTextPanelCloneElement(objTile);
11116		else
11117			var objTextPanel = getTextPanelElement(objTile);
11118		
11119		
11120		if(!objTextPanel)
11121			return(0);
11122		
11123		var objSize = g_functions.getElementSize(objTextPanel);
11124		return(objSize.height);
11125	}
11126	
11127	
11128	/**
11129	 * get button link
11130	 */
11131	function getButtonLink(objTile){
11132		var objButton = objTile.find(".ug-icon-link");
11133		if(objButton.length == 0)
11134			return(null);
11135		
11136		return objButton;
11137	}
11138
11139	
11140	/**
11141	 * get tile ratio
11142	 */
11143	function getTileRatio(objTile){
11144		
11145		//global ratio
11146		var ratio = g_temp.ratioByHeight;
11147		
11148		switch(g_options.tile_size_by){
11149			default:		//global ratio
11150				ratio = g_temp.ratioByHeight;
11151			break;
11152			case t.sizeby.IMAGE_RATIO:
11153
11154				if(!objTile)
11155					throw new Error("tile should be given for tile ratio");
11156				
11157				var item = t.getItemByTile(objTile);
11158								
11159				if(typeof item.thumbRatioByHeight != "undefined"){
11160				
11161					if(item.thumbRatioByHeight == 0){
11162						trace(item);
11163						throw new Error("the item ratio not inited yet");
11164					}
11165				
11166					ratio = item.thumbRatioByHeight;
11167				}
11168			
11169			break;
11170			case t.sizeby.CUSTOM:
11171				return null;
11172			break;
11173		}
11174				
11175		return(ratio);
11176	}
11177	
11178	
11179	/**
11180	 * get button zoom
11181	 */
11182	function getButtonZoom(objTile){
11183		var objButton = objTile.find(".ug-button-play");
11184		
11185		if(objButton.length == 0)
11186			return(null);
11187		
11188		return objButton;
11189	}
11190	
11191	
11192	/**
11193	 * tells if the tile is over style
11194	 */
11195	function isOverStyle(objTile){
11196		
11197		if(objTile.hasClass("ug-thumb-over"))
11198			return(true);
11199		
11200		return(false);
11201	}
11202	
11203	
11204	/**
11205	 * check if the tile is clickable
11206	 */
11207	function isTileClickable(objTile){
11208		
11209		return objTile.hasClass("ug-tile-clickable");
11210	}
11211	
11212	
11213	/**
11214	 * return if the items icon always on
11215	 */
11216	function isItemIconAlwaysOn(objItem){
11217		
11218		if(g_options.tile_enable_icons == true && g_temp.isVideoplayIconAlwaysOn == true && objItem.type != "image")
11219			return(true);
11220		
11221		return(false);
11222	}
11223
11224	
11225	function _________________SETTERS________________(){};
11226	
11227	
11228	/**
11229	 * position tile images elements
11230	 * width, height - tile width height
11231	 */
11232	function positionElements_images(objTile, width, height, visibleOnly){
11233		
11234		var objImageOverlay = getTileOverlayImage(objTile);
11235		var objThumbImage = t.getTileImage(objTile);
11236		var objImageEffect = getTileImageEffect(objTile);
11237		
11238		//reduce borders
11239		width -= g_temp.tileInnerReduce;
11240		height -= g_temp.tileInnerReduce;
11241		
11242		var imagePosy = null;
11243		
11244		//reduce textpanel height
11245		if(g_temp.isTextpanelOutside == true){
11246
11247			var textHeight = getTextPanelHeight(objTile);
11248			height -= textHeight;
11249
11250			if(g_options.tile_textpanel_position == "top"){
11251				imagePosy = textHeight;
11252			}
11253			
11254			/**
11255			 * if has image container
11256			 */
11257			if(g_temp.hasImageContainer == true){
11258				var objImageContainer = getTileImageContainer(objTile);
11259				g_functions.setElementSize(objImageContainer, width, height);
11260				
11261				if(imagePosy !== null)
11262					g_functions.placeElement(objImageContainer, 0, imagePosy);
11263			}
11264			
11265		}
11266		
11267		//scale image
11268		if(g_options.tile_enable_image_effect == false){
11269
11270			g_functions.scaleImageCoverParent(objThumbImage, width, height);
11271			
11272			if(g_temp.hasImageContainer == false && imagePosy !== null)
11273				g_functions.placeElement(objThumbImage, 0, imagePosy);
11274
11275		}else{	//width the effect
11276			
11277			//set what to resize
11278			var dontResize = "nothing";
11279			if(visibleOnly === true && g_temp.isTextpanelOutside == false){
11280				if(g_options.tile_image_effect_reverse == true){
11281					dontResize = "effect";
11282				}else{
11283					dontResize = "image";
11284				}
11285			}
11286
11287			//resize image effect
11288			if(dontResize != "effect"){
11289				g_functions.setElementSize(objImageOverlay, width, height);
11290				
11291				if(imagePosy !== null)
11292					g_functions.placeElement(objImageOverlay, 0, imagePosy);
11293				
11294				g_functions.scaleImageCoverParent(objImageEffect, width, height);
11295			}
11296			
11297
11298			//resize image
11299			if(dontResize != "image"){
11300				
11301				if(g_temp.hasImageContainer == true){
11302					g_functions.scaleImageCoverParent(objThumbImage, width, height);
11303				}else{
11304					
11305					//if can't clone, resize
11306					if(dontResize == "effect"){
11307						g_functions.scaleImageCoverParent(objThumbImage, width, height);
11308						if(imagePosy !== null)
11309							g_functions.placeElement(objThumbImage, 0, imagePosy);
11310					}
11311					else
11312						g_functions.cloneElementSizeAndPos(objImageEffect, objThumbImage, false, null, imagePosy);
11313					
11314				}
11315				
11316			}
11317
11318			
11319			
11320		}
11321
11322	}
11323	
11324	
11325	/**
11326	 * position text panel
11327	 * panelType - default or clone
11328	 */
11329	function positionElements_textpanel(objTile, panelType, tileWidth, tileHeight){
11330		
11331		var panelWidth = null;
11332		if(tileWidth)
11333			panelWidth = tileWidth - g_temp.tileInnerReduce;
11334
11335		if(tileHeight)
11336			tileHeight -= g_temp.tileInnerReduce;
11337		
11338		if(panelType == "clone"){
11339			var objTextPanelClone = getTextPanelClone(objTile);
11340			objTextPanelClone.refresh(true, true, panelWidth);
11341			var objItem = t.getItemByTile(objTile);
11342			objItem.textPanelCloneSizeSet = true;
11343			
11344			return(false);
11345		}
11346		
11347		var objTextPanel = getTextPanel(objTile);
11348		
11349		if(!objTextPanel)
11350			return(false);
11351		
11352		var panelHeight = null;
11353				
11354		//set panel height also
11355		if(g_temp.isTextpanelOutside == true)
11356			panelHeight = getTextPanelHeight(objTile);
11357		
11358		objTextPanel.refresh(false, true, panelWidth, panelHeight);
11359		
11360		var isPosition = (g_options.tile_textpanel_always_on == true || g_options.tile_textpanel_appear_type == "fade");
11361		
11362		if(isPosition){
11363			
11364			if(g_temp.isTextpanelOutside == true && tileHeight && g_options.tile_textpanel_position == "bottom"){
11365			
11366				var posy = tileHeight - panelHeight;
11367				objTextPanel.positionPanel(posy);
11368			}else
11369				objTextPanel.positionPanel();
11370		}
11371		
11372	}
11373		
11374	
11375	/**
11376	 * position the elements
11377	 */
11378	function positionElements(objTile){
11379		
11380		var objItem = t.getItemByTile(objTile);
11381		var objButtonZoom = getButtonZoom(objTile);
11382		var objButtonLink = getButtonLink(objTile);
11383		var sizeTile = g_functions.getElementSize(objTile);
11384				
11385		positionElements_images(objTile, sizeTile.width, sizeTile.height);
11386		
11387		//position text panel:
11388		if(g_options.tile_enable_textpanel == true)
11389			positionElements_textpanel(objTile, "regular", sizeTile.width, sizeTile.height);
11390		
11391		
11392		//position overlay:
11393		var overlayWidth = sizeTile.width - g_temp.tileInnerReduce;
11394		var overlayHeight = sizeTile.height - g_temp.tileInnerReduce;
11395		var overlayY = 0;
11396		if(g_temp.isTextpanelOutside == true){
11397			var textHeight = getTextPanelHeight(objTile);
11398			overlayHeight -= textHeight;
11399			if(g_options.tile_textpanel_position == "top")
11400				overlayY = textHeight;
11401		}
11402		
11403		var objOverlay = getTileOverlay(objTile);
11404		g_functions.setElementSizeAndPosition(objOverlay, 0, overlayY, overlayWidth, overlayHeight);
11405		
11406		//set vertical gap for icons
11407		if(objButtonZoom || objButtonLink){
11408
11409			var gapVert = 0;
11410			if( g_options.tile_enable_textpanel == true && g_temp.isTextPanelHidden == false && g_temp.isTextpanelOutside == false){
11411				var objTextPanelElement = getTextPanelElement(objTile);
11412				var texPanelSize = g_functions.getElementSize(objTextPanelElement);
11413				if(texPanelSize.height > 0)
11414					gapVert = Math.floor((texPanelSize.height / 2) * -1);
11415			}
11416
11417		}
11418		
11419		if(objButtonZoom && objButtonLink){
11420			var sizeZoom = g_functions.getElementSize(objButtonZoom);
11421			var sizeLink = g_functions.getElementSize(objButtonLink);
11422			var spaceBetween = g_options.tile_space_between_icons;
11423			
11424			var buttonsWidth = sizeZoom.width + spaceBetween + sizeLink.width;
11425			var buttonsX = Math.floor((sizeTile.width - buttonsWidth) / 2);
11426			
11427			//trace("X: "+buttonsX+" "+"space: " + spaceBetween);
11428			
11429			//if space more then padding, calc even space.
11430			if(buttonsX < spaceBetween){
11431				spaceBetween = Math.floor((sizeTile.width - sizeZoom.width - sizeLink.width) / 3);
11432				buttonsWidth = sizeZoom.width + spaceBetween + sizeLink.width;
11433				buttonsX = Math.floor((sizeTile.width - buttonsWidth) / 2);
11434			}
11435
11436			g_functions.placeElement(objButtonZoom, buttonsX, "middle", 0 ,gapVert);
11437			g_functions.placeElement(objButtonLink, buttonsX + sizeZoom.width + spaceBetween, "middle", 0, gapVert);
11438						
11439		}else{
11440			
11441			if(objButtonZoom)
11442				g_functions.placeElement(objButtonZoom, "center", "middle", 0, gapVert);
11443			
11444			if(objButtonLink)
11445				g_functions.placeElement(objButtonLink, "center", "middle", 0, gapVert);
11446				
11447		}
11448		
11449		if(objButtonZoom)
11450			objButtonZoom.show();
11451		
11452		if(objButtonLink)
11453			objButtonLink.show();
11454	}
11455
11456	
11457	/**
11458	 * set tiles htmls
11459	 */
11460	this.setHtml = function(objParent, isAppend){
11461		g_objParentWrapper = objParent;
11462		
11463		if(isAppend !== true)
11464			modifyOptionsBeforeRender();
11465		
11466		g_thumbs.setHtmlThumbs(objParent, isAppend);
11467	}
11468	
11469	
11470	
11471	/**
11472	 * set the overlay effect
11473	 */
11474	function setImageOverlayEffect(objTile, isActive){
11475		
11476		var objItem = t.getItemByTile(objTile);
11477		var objOverlayImage = getTileOverlayImage(objTile);
11478		
11479		var animationDuration = g_options.thumb_transition_duration;
11480		
11481		if(g_options.tile_image_effect_reverse == false){
11482			
11483			var objThumbImage = t.getTileImage(objTile);
11484			
11485			if(isActive){
11486				objThumbImage.fadeTo(0,1);			
11487				objOverlayImage.stop(true).fadeTo(animationDuration, 0);
11488			}
11489			else
11490				objOverlayImage.stop(true).fadeTo(animationDuration, 1);
11491			
11492		}else{
11493			
11494			if(isActive){
11495				objOverlayImage.stop(true).fadeTo(animationDuration, 1);
11496			}
11497			else{
11498				objOverlayImage.stop(true).fadeTo(animationDuration, 0);
11499			}
11500		}
11501
11502	}
11503	
11504	
11505	/**
11506	 * set textpanel effect
11507	 */
11508	function setTextpanelEffect(objTile, isActive){
11509		
11510		var animationDuration = g_options.thumb_transition_duration;
11511		
11512		var objTextPanel = getTextPanelElement(objTile);
11513		if(!objTextPanel)
11514			return(true);
11515				
11516		if(g_options.tile_textpanel_appear_type == "slide"){
11517			
11518			var panelSize = g_functions.getElementSize(objTextPanel);
11519			if(panelSize.width == 0)
11520				return(false);
11521			
11522			var startPos = -panelSize.height;
11523			var endPos = 0;
11524			var startClass = {}, endClass = {};
11525			
11526			var posName = "bottom";
11527			if(g_options.tile_textpanel_position == "inside_top")
11528				posName = "top";
11529			
11530			startClass[posName] = startPos+"px";
11531			endClass[posName] = endPos+"px";
11532						
11533			if(isActive == true){
11534								
11535				objTextPanel.fadeTo(0,1);
11536				
11537				if(objTextPanel.is(":animated") == false)
11538					objTextPanel.css(startClass);
11539				
11540				endClass["opacity"] = 1;
11541					
11542				objTextPanel.stop(true).animate(endClass, animationDuration);
11543				
11544			}else{
11545				
11546				objTextPanel.stop(true).animate(startClass, animationDuration);
11547				
11548			}
11549			
11550		}else{		//fade effect
11551			
11552			if(isActive == true){
11553				objTextPanel.stop(true).fadeTo(animationDuration, 1);
11554			}else{
11555				objTextPanel.stop(true).fadeTo(animationDuration, 0);
11556			}
11557			
11558		}
11559		
11560	}
11561	
11562
11563	/**
11564	 * set thumb border effect
11565	 */
11566	function setIconsEffect(objTile, isActive, noAnimation){
11567		
11568		var animationDuration = g_options.thumb_transition_duration;
11569		if(noAnimation && noAnimation === true)
11570			animationDuration = 0;
11571		
11572		var g_objIconZoom = getButtonZoom(objTile);
11573		var g_objIconLink = getButtonLink(objTile);
11574		var opacity = isActive?1:0;
11575		
11576		if(g_objIconZoom)
11577			g_objIconZoom.stop(true).fadeTo(animationDuration, opacity);
11578		
11579		if(g_objIconLink)
11580			g_objIconLink.stop(true).fadeTo(animationDuration, opacity);
11581		
11582	}
11583	
11584	
11585	
11586	/**
11587	 * set tile over style
11588	 */
11589	function setOverStyle(data, objTile){
11590				
11591		objTile = jQuery(objTile);
11592				
11593		if(g_options.tile_enable_image_effect)
11594			setImageOverlayEffect(objTile, true);
11595
11596		if(g_options.tile_enable_textpanel == true && g_options.tile_textpanel_always_on == false && g_temp.isTextPanelHidden == false)
11597			setTextpanelEffect(objTile, true);
11598		
11599		//show/hide icons - if saparate (if not, they are part of the overlay)
11600		//if the type is video and icon always on - the icon should stay
11601		if(g_temp.isSaparateIcons && g_options.tile_enable_icons == true){
11602			var isSet = (g_options.thumb_overlay_reverse == true);
11603			
11604			var objItem = t.getItemByTile(objTile);
11605			if(isItemIconAlwaysOn(objItem) == false)
11606				setIconsEffect(objTile, isSet, false);
11607			
11608		}
11609		
11610	}
11611	
11612	
11613	/**
11614	 * set normal style
11615	 */
11616	function setNormalStyle(data, objTile){
11617		
11618		objTile = jQuery(objTile);
11619		
11620		if(g_options.tile_enable_image_effect)
11621			setImageOverlayEffect(objTile, false);
11622		
11623		if(g_options.tile_enable_textpanel == true && g_options.tile_textpanel_always_on == false)
11624			setTextpanelEffect(objTile, false);
11625		
11626		//show/hide icons - if saparate (if not, they are part of the overlay)
11627		if(g_temp.isSaparateIcons == true && g_options.tile_enable_icons == true){
11628			
11629			var isSet = (g_options.thumb_overlay_reverse == true)?false:true;
11630			
11631			var objItem = t.getItemByTile(objTile);
11632			if(isItemIconAlwaysOn(objItem) == false)
11633				setIconsEffect(objTile, isSet, false);
11634			else{	//make icon always appear
11635				setIconsEffect(objTile, true, true);
11636			}
11637			
11638		}
11639		
11640	}
11641	
11642	
11643	/**
11644	 * set all tiles normal style
11645	 */
11646	function setAllTilesNormalStyle(objTileExcept){
11647		
11648		var objTiles = g_thumbs.getThumbs().not(objTileExcept);
11649		objTiles.each(function(index, objTile){
11650			g_thumbs.setThumbNormalStyle(jQuery(objTile));
11651		});
11652		
11653	}
11654	
11655	
11656	function _________________EVENTS________________(){};
11657	
11658	
11659	/**
11660	 * on tile size change, place elements
11661	 */
11662	function onSizeChange(data, objTile, forcePosition){
11663
11664		objTile = jQuery(objTile);
11665		
11666		//position elements only if the image loaded (placed)
11667		if(g_options.tile_visible_before_image == true && objTile.data("image_placed") !== true && forcePosition !== true)
11668			return(true);
11669
11670		positionElements(objTile);
11671		
11672		g_thumbs.setThumbNormalStyle(objTile);
11673	}
11674	
11675	
11676	/**
11677	 * on place image event after images loaded
11678	 */
11679	function onPlaceImage(data, objTile, objImage){
11680		
11681		positionElements(objTile);
11682		objImage.fadeTo(0,1);
11683		
11684		objTile.data("image_placed", true);
11685	}
11686	
11687	
11688	/**
11689	 * on tile click on mobile devices on normal state
11690	 * set the tile over state
11691	 */
11692	function onMobileClick(objTile){
11693
11694		if(isTileClickable(objTile) == true){
11695			g_objThis.trigger(t.events.TILE_CLICK, objTile);
11696			return(true);
11697		}
11698		
11699		if(isOverStyle(objTile) == false){
11700			setAllTilesNormalStyle(objTile);			
11701			g_thumbs.setThumbOverStyle(objTile);
11702		}
11703		
11704	}
11705	
11706	
11707	/**
11708	 * on tile click event
11709	 */
11710	function onTileClick(event){
11711				
11712		var objTile = jQuery(this);
11713		
11714		var tagname = objTile.prop("tagName").toLowerCase();
11715		var isApproved = true;
11716		if(g_temp.funcParentApproveClick && g_temp.funcParentApproveClick() == false)
11717			isApproved = false;
11718				
11719		if(tagname == "a"){
11720			
11721			if(isApproved == false)
11722				event.preventDefault();
11723							
11724		}else{		//in case of div
11725			
11726			if(isOverStyle(objTile) == false){	//mobile click version
11727				
11728				if(isApproved == true)
11729					onMobileClick(objTile);
11730								
11731			}else{
11732				if(isTileClickable(objTile) == false)
11733					return(true);
11734				
11735				if(isApproved == true)
11736					g_objThis.trigger(t.events.TILE_CLICK, objTile);
11737			}
11738			
11739			
11740		}
11741		
11742	}
11743	
11744	
11745	/**
11746	 * click on zoom button (as tile click)
11747	 */
11748	function onZoomButtonClick(event){
11749				
11750		event.stopPropagation();
11751		
11752		var objTile = jQuery(this).parents(".ug-tile");
11753		
11754		var isApproved = true;
11755		
11756		if(g_temp.funcParentApproveClick && g_temp.funcParentApproveClick() == false)
11757			isApproved = false;
11758		
11759		if(isOverStyle(objTile) == false){
11760			onMobileClick(objTile);
11761			return(true);
11762		}
11763			
11764		if(isApproved == true){
11765			g_objThis.trigger(t.events.TILE_CLICK, objTile);
11766			return(false);
11767		}
11768		
11769	}
11770	
11771	
11772	/**
11773	 * on link icon click
11774	 */
11775	function onLinkButtonClick(event){
11776		var objTile = jQuery(this).parents(".ug-tile");
11777				
11778		if(g_temp.funcParentApproveClick && g_temp.funcParentApproveClick() == false)
11779			event.preventDefault();
11780		
11781		//allow click only from over style
11782		if(isOverStyle(objTile) == false && g_options.tile_as_link == false){
11783			event.preventDefault();
11784			onMobileClick(objTile);
11785		}
11786		
11787	}
11788	
11789	
11790	/**
11791	 * init events
11792	 */
11793	this.initEvents = function(){
11794				
11795		g_thumbs.initEvents();
11796		
11797		//connect the over and normal style of the regular thumbs
11798		jQuery(g_thumbs).on(g_thumbs.events.SETOVERSTYLE, setOverStyle);
11799		jQuery(g_thumbs).on(g_thumbs.events.SETNORMALSTYLE, setNormalStyle);
11800		jQuery(g_thumbs).on(g_thumbs.events.PLACEIMAGE, onPlaceImage);
11801		
11802		g_objWrapper.on(g_temp.eventSizeChange, onSizeChange);
11803		
11804		g_objParentWrapper.on("click", ".ug-tile", onTileClick);
11805		
11806		g_objParentWrapper.on("click", ".ug-tile .ug-button-play", onZoomButtonClick);
11807		
11808		g_objParentWrapper.on("click", ".ug-tile .ug-icon-link", onLinkButtonClick);
11809	}
11810	
11811	
11812	/**
11813	 * destroy the element events
11814	 */
11815	this.destroy = function(){
11816		
11817		g_objParentWrapper.off("click", ".ug-tile");
11818		g_objParentWrapper.off("click", ".ug-tile .ug-button-play");
11819		g_objParentWrapper.off("click", ".ug-tile .ug-icon-link");
11820		
11821		jQuery(g_thumbs).off(g_thumbs.events.SETOVERSTYLE);
11822		jQuery(g_thumbs).off(g_thumbs.events.SETNORMALSTYLE);
11823		jQuery(g_thumbs).off(g_thumbs.events.PLACEIMAGE);
11824		g_objWrapper.off(g_temp.eventSizeChange);
11825		
11826		if(g_options.tile_enable_textpanel == true){
11827			var objThumbs = g_thumbs.getThumbs();
11828			jQuery.each(objThumbs, function(index, thumb){				
11829				var textPanel = getTextPanel(jQuery(thumb));
11830				if(textPanel)
11831					textPanel.destroy();
11832			});
11833		}
11834		
11835		g_thumbs.destroy();
11836
11837	}
11838
11839	
11840	/**
11841	 * external init
11842	 */
11843	this.init = function(gallery, g_thumbs, customOptions){
11844		
11845		init(gallery, g_thumbs, customOptions);
11846	}
11847	
11848	/**
11849	 * set fixed mode
11850	 */
11851	this.setFixedMode = function(){
11852		
11853		g_options.tile_size_by = t.sizeby.GLOBAL_RATIO;
11854		g_options.tile_visible_before_image = true;
11855	}
11856	
11857	
11858	/**
11859	 * set parent approve click function
11860	 */
11861	this.setApproveClickFunction = function(funcApprove){
11862		g_temp.funcParentApproveClick = funcApprove;
11863	}
11864	
11865	
11866	
11867	/**
11868	 * resize tile. If no size given, resize to original size
11869	 * the resize mode taken from resize modes constants, default is full
11870	 */
11871	this.resizeTile = function(objTile, newWidth, newHeight, resizeMode){
11872		
11873			//if textpanel outside - refresh the textpanel first
11874			if(g_temp.isTextpanelOutside == true)
11875				positionElements_textpanel(objTile, "clone", newWidth);
11876			
11877			if(!newWidth){
11878				
11879				var newWidth = g_options.tile_width;
11880				var newHeight = g_options.tile_height;
11881				
11882			}else{		//only height is missing
11883				if(!newHeight){
11884					
11885					var newHeight = t.getTileHeightByWidth(newWidth, objTile);
11886				}
11887			}
11888						
11889			g_functions.setElementSize(objTile, newWidth, newHeight);
11890			
11891			switch(resizeMode){
11892				default:
11893				case t.resizemode.FULL:
11894					t.triggerSizeChangeEvent(objTile, true);
11895				break;
11896				case t.resizemode.WRAPPER_ONLY:
11897					return(true);
11898				break;
11899				case t.resizemode.VISIBLE_ELEMENTS:
11900					
11901					if(g_temp.funcCustomTileHtml){
11902						t.triggerSizeChangeEvent(objTile, true);
11903						return(true);
11904					}
11905					
11906					//resize images
11907					positionElements_images(objTile, newWidth, newHeight, true);
11908					
11909					//resize text panel, if visible
11910					if(g_options.tile_enable_textpanel == true && g_options.tile_textpanel_always_on == true && newWidth){
11911						positionElements_textpanel(objTile, "regular", newWidth, newHeight);
11912					}
11913					
11914				break;
11915			}
11916		
11917	}
11918
11919	
11920	/**
11921	 * resize all tiles 
11922	 */
11923	this.resizeAllTiles = function(newWidth, resizeMode, objTiles){
11924		
11925		modifyOptionsBeforeRender();
11926		
11927		var newHeight = null;
11928		
11929		if(g_options.tile_size_by == t.sizeby.GLOBAL_RATIO)
11930			newHeight = t.getTileHeightByWidth(newWidth);
11931		
11932		if(!objTiles)
11933			var objTiles = g_thumbs.getThumbs();
11934		
11935		objTiles.each(function(index, objTile){
11936			t.resizeTile(jQuery(objTile), newWidth, newHeight, resizeMode);
11937		});
11938		
11939	}
11940	
11941	
11942	/**
11943	 * trigger size change events
11944	 * the force is only for fixed size mode
11945	 */
11946	this.triggerSizeChangeEvent = function(objTile, isForce){
11947		
11948		if(!objTile)
11949			return(false);
11950		
11951		if(!isForce)
11952			var isForce = false;
11953		
11954		g_objWrapper.trigger(g_temp.eventSizeChange, [objTile, isForce]);
11955		
11956	}
11957	
11958	
11959	/**
11960	 * trigger size change event to all tiles
11961	 * the force is only for fixed mode
11962	 */
11963	this.triggerSizeChangeEventAllTiles = function(isForce){
11964		
11965		var objThumbs = g_thumbs.getThumbs();
11966
11967		objThumbs.each(function(){
11968			var objTile = jQuery(this);
11969			
11970			t.triggerSizeChangeEvent(objTile, isForce);
11971			
11972		});
11973		
11974	}
11975	
11976	
11977	
11978	
11979	
11980	/**
11981	 * disable all events
11982	 */
11983	this.disableEvents = function(){
11984		var objThumbs = g_thumbs.getThumbs();
11985		objThumbs.css("pointer-events", "none");
11986	}
11987	
11988	
11989	/**
11990	 * enable all events
11991	 */
11992	this.enableEvents = function(){
11993		var objThumbs = g_thumbs.getThumbs();
11994		objThumbs.css("pointer-events", "auto");
11995	}
11996	
11997	
11998	/**
11999	 * set new options
12000	 */
12001	this.setOptions = function(newOptions){
12002		g_options = jQuery.extend(g_options, newOptions);
12003		g_thumbs.setOptions(newOptions);
12004	}
12005	
12006	
12007	/**
12008	 * set new tile size, this function will not resize, and keep ratio
12009	 */
12010	this.setTileSizeOptions = function(newTileWidth){
12011		
12012		if(g_options.tile_size_by !== t.sizeby.GLOBAL_RATIO)
12013			throw new Error("setNewTileOptions works with global ration only");
12014		
12015		g_options.tile_width = newTileWidth;
12016		g_options.tile_height = Math.floor(newTileWidth * g_temp.ratioByHeight);
12017		
12018		
12019	}
12020	
12021	
12022	/**
12023	 * set custom tile html function
12024	 */
12025	this.setCustomFunctions = function(funcCustomHtml, funcPositionElements){
12026		g_temp.funcCustomTileHtml = funcCustomHtml;
12027		g_temp.funcCustomPositionElements = funcPositionElements;
12028	}
12029	
12030	
12031	/**
12032	 * run the tile design
12033	 */
12034	this.run = function(newOnly){
12035		
12036		//resize all tiles
12037		var getMode = g_thumbs.type.GET_THUMBS_ALL;
12038		if(newOnly === true)
12039			getMode = g_thumbs.type.GET_THUMBS_NEW;
12040		
12041		var objThumbs = g_thumbs.getThumbs(getMode);
12042		
12043		if(g_options.tile_size_by == t.sizeby.GLOBAL_RATIO){
12044			t.resizeAllTiles(g_options.tile_width, t.resizemode.WRAPPER_ONLY, objThumbs);
12045		}
12046		
12047		//hide original image if image effect active
12048		if(g_options.tile_enable_image_effect == true && g_options.tile_image_effect_reverse == false)
12049			objThumbs.children(".ug-thumb-image").fadeTo(0,0);
12050		
12051		g_thumbs.setHtmlProperties(objThumbs);
12052		
12053		if(g_options.tile_visible_before_image == true){
12054			
12055			//if textpanel outside - refresh the textpanel first			
12056			objThumbs.children(".ug-thumb-image").fadeTo(0,0);
12057			g_thumbs.loadThumbsImages();
12058		}
12059		
12060	}
12061
12062	
12063	this._____________EXTERNAL_GETTERS____________=function(){};
12064	
12065	
12066	/**
12067	 * get thumbs general option
12068	 */
12069	this.getObjThumbs = function(){
12070		return g_thumbs;
12071	}
12072	
12073	/**
12074	 * get options
12075	 */
12076	this.getOptions = function(){
12077		return g_options;
12078	}
12079
12080	/**
12081	 * get tile image
12082	 */
12083	this.getTileImage = function(objTile){
12084		var objImage = objTile.find("img.ug-thumb-image");
12085		return(objImage);
12086	}
12087
12088	
12089	/**
12090	 * get item from tile
12091	 */
12092	this.getItemByTile = function(objTile){
12093		return g_thumbs.getItemByThumb(objTile);
12094	}
12095	
12096	
12097	/**
12098	 * get tile height by width
12099	 */
12100	this.getTileHeightByWidth = function(newWidth, objTile){
12101		
12102		var ratio = getTileRatio(objTile);
12103		
12104		if(ratio === null)
12105			return(null);
12106		
12107		var height = Math.floor( (newWidth - g_temp.tileInnerReduce) * ratio) + g_temp.tileInnerReduce;
12108		
12109		if(objTile && g_temp.isTextpanelOutside == true && g_options.tile_size_by == t.sizeby.IMAGE_RATIO)
12110			height += getTextPanelHeight(objTile);
12111		
12112		return(height);
12113	}
12114	
12115	
12116	/**
12117	 * get tile original size
12118	 */
12119	this.getTileImageSize = function(objTile){
12120        var objItem = t.getItemByTile(objTile);
12121        if(!objItem.thumbWidth || !objItem.thumbHeight)
12122        	throw new Error("Can't get image size - image not inited.");
12123        
12124        var objSize = {
12125        		width: objItem.thumbWidth,
12126        		height: objItem.thumbHeight
12127        };
12128        
12129        return(objSize);
12130	}
12131	
12132	
12133	/**
12134	 * get tile size
12135	 */
12136	this.getGlobalTileSize = function(){
12137		
12138		if(g_options.tile_size_by != t.sizeby.GLOBAL_RATIO)
12139			throw new Error("The size has to be global ratio");
12140		
12141		var objSize = {
12142				width: g_options.tile_width,
12143				height: g_options.tile_height
12144		};
12145		
12146		return(objSize);
12147	}
12148	
12149	
12150}
12151
12152/**
12153 * avia control class
12154 * addon to strip gallery
12155 */
12156function UGAviaControl(){
12157
12158	var g_parent, g_gallery, g_objects, g_objStrip, g_objStripInner, g_options;
12159	var g_isVertical;
12160	
12161	var g_temp = {
12162		touchEnabled:false,			//variable that tells if touch event was before move event
12163		isMouseInsideStrip: false,
12164		strip_finalPos:0,
12165		handle_timeout:"",
12166		isStripMoving:false,
12167		isControlEnabled: true
12168	};
12169	
12170	
12171	/**
12172	 * enable the control
12173	 */
12174	this.enable = function(){
12175		g_temp.isControlEnabled = true;
12176	}
12177	
12178	/**
12179	 * disable the control
12180	 */
12181	this.disable = function(){
12182		g_temp.isControlEnabled = false;		
12183	}
12184	
12185	/**
12186	 * init function for avia controls
12187	 */
12188	this.init = function(objParent){
12189		g_parent = objParent;
12190		
12191		g_objects = objParent.getObjects();
12192				
12193		g_gallery = g_objects.g_gallery;
12194		
12195		g_objStrip = g_objects.g_objStrip;
12196		g_objStripInner = g_objects.g_objStripInner;
12197		g_options = g_objects.g_options;
12198		g_isVertical = g_objects.isVertical;		
12199				
12200		initEvents();
12201	}
12202	
12203	/**
12204	 * get mouse position from event according the orientation
12205	 */
12206	function getMousePos(event){
12207		
12208		if(g_isVertical == false)
12209			return(event.pageX);
12210		
12211		return(event.pageY);
12212	}
12213	
12214	/**
12215	 * handle avia strip control event on body mouse move
12216	 */
12217	function initEvents(event){
12218		
12219		//make sure that the avia control will not work on touch devices
12220		jQuery("body").on("touchstart", function(event){
12221			
12222			if(g_temp.isControlEnabled == false)
12223				return(true);
12224			
12225			g_temp.touchEnabled = true;
12226			
12227		});
12228		
12229		//on body move
12230		jQuery("body").mousemove(function(event){
12231			
12232			if(g_temp.isControlEnabled == false)
12233				return(true);
12234									
12235			//protection for touch devices, disable the avia events
12236			if(g_temp.touchEnabled == true){
12237				jQuery("body").off("mousemove");
12238				return(true);
12239			}
12240			
12241			g_temp.isMouseInsideStrip = g_objStrip.ismouseover();
12242			var strip_touch_active = g_parent.isTouchMotionActive();
12243			
12244			if(g_temp.isMouseInsideStrip == true && strip_touch_active == false){
12245				
12246				var mousePos = getMousePos(event);
12247				
12248				moveStripToMousePosition(mousePos);
12249			}else{
12250				stopStripMovingLoop();
12251			}
12252			
12253		});
12254						
12255	}
12256	
12257	
12258	/**
12259	 * destroy the avia control events
12260	 */
12261	this.destroy = function(){
12262		
12263		jQuery("body").off("touchstart");
12264		jQuery("body").off("mousemove");
12265
12266	}
12267	
12268	
12269	/**
12270	 * get inner y position according mouse y position on the strip
12271	 */
12272	function getInnerPosY(mouseY){
12273
12274		var innerOffsetTop = g_options.strip_padding_top;
12275		var innerOffsetBottom = g_options.strip_padding_bottom;
12276
12277		var stripHeight = g_objStrip.height();
12278		var innerHeight = g_objStripInner.height();		
12279		
12280		//if all thumbs visible, no need to move
12281		if(stripHeight >
12281 innerHeight)
12282			return(null);
12283		
12284		//find y position inside the strip
12285		var stripOffset = g_objStrip.offset();		
12286		var offsetY = stripOffset.top;
12287		var posy = mouseY - offsetY - innerOffsetTop;
12288		if(posy < 0)
12289			return(null);
12290		
12291		//set measure line parameters
12292		var mlineStart = g_options.thumb_height;
12293		var mlineEnd = stripHeight - g_options.thumb_height;
12294		var mLineSize = mlineEnd - mlineStart;
12295				
12296		//fix position borders on the measure line
12297		if(posy < mlineStart)
12298			posy = mlineStart;
12299		
12300		if(posy > mlineEnd)
12301			posy = mlineEnd;
12302		
12303		//count the ratio of the position on the measure line
12304		var ratio = (posy - mlineStart) / mLineSize;
12305		var innerPosY = (innerHeight - stripHeight) * ratio;
12306		innerPosY = Math.round(innerPosY) * -1 + innerOffsetTop;
12307		
12308		return(innerPosY);
12309	}
12310
12311	
12312	/**
12313	 * get inner x position according mouse x position on the strip
12314	 */
12315	function getInnerPosX(mouseX){
12316		
12317		var innerOffsetLeft = g_options.strip_padding_left;
12318		var innerOffsetRight = g_options.strip_padding_right;
12319		
12320		var stripWidth = g_objStrip.width() - innerOffsetLeft - innerOffsetRight;
12321		var innerWidth = g_objStripInner.width();
12322		
12323		//if all thumbs visible, no need to move
12324		if(stripWidth > innerWidth)
12325			return(null);
12326		
12327		var stripOffset = g_objStrip.offset();
12328		var offsetX = stripOffset.left;
12329		var posx = mouseX - offsetX - innerOffsetLeft;
12330		
12331		//set measure line parameters
12332		var mlineStart = g_options.thumb_width;
12333		var mlineEnd = stripWidth - g_options.thumb_width;
12334		var mLineSize = mlineEnd - mlineStart;
12335		
12336		//fix position borders on the measure line
12337		if(posx < mlineStart)
12338			posx = mlineStart;
12339		
12340		if(posx > mlineEnd)
12341			posx = mlineEnd;
12342		
12343		//count the ratio of the position on the measure line
12344		var ratio = (posx - mlineStart) / mLineSize;
12345		var innerPosX = (innerWidth - stripWidth) * ratio;
12346		innerPosX = Math.round(innerPosX) * -1 + innerOffsetLeft;
12347		
12348		
12349		return(innerPosX);
12350	}
12351		
12352		
12353	/**
12354	 * move strip stap to final position
12355	 */
12356	function moveStripStep(){
12357		
12358		if(g_temp.is_strip_moving == false){
12359			return(false);
12360		}
12361		
12362		var innerPos = g_parent.getInnerStripPos();
12363				
12364		if(Math.floor(innerPos) == Math.floor(g_temp.strip_finalPos)){
12365			stopStripMovingLoop();
12366		}
12367		
12368		//calc step
12369		var diff = Math.abs(g_temp.strip_finalPos - innerPos);
12370		
12371		var dpos;
12372		if(diff < 1){
12373			dpos = diff;
12374		}
12375		else{
12376		
12377			dpos = diff / 4;
12378			if(dpos > 0 && dpos < 1)
12379				dpos = 1;
12380		}		
12381		
12382		if(g_temp.strip_finalPos < innerPos)
12383			dpos = dpos * -1;
12384				
12385		var newPos = innerPos + dpos;
12386		
12387		g_parent.positionInnerStrip(newPos);
12388		
12389	}
12390	
12391	
12392	/**
12393	 * start loop of strip moving
12394	 */
12395	function startStripMovingLoop(){
12396		
12397		if(g_temp.isStripMoving == true)
12398			return(false);
12399			
12400		g_temp.isStripMoving = true;
12401		g_temp.handle_timeout = setInterval(moveStripStep,10);
12402	}
12403	
12404	/**
12405	 * stop loop of strip moving
12406	 */
12407	function stopStripMovingLoop(){
12408		
12409		if(g_temp.isStripMoving == false)
12410			return(false);
12411			
12412		g_temp.isStripMoving = false;
12413		g_temp.handle_timeout = clearInterval(g_temp.handle_timeout);
12414	}
12415
12416	/**
12417	 * get inner position according the orientation
12418	 * taken by the mouse position
12419	 */
12420	function getInnerPos(mousePos){
12421		
12422		if(g_isVertical == false)
12423			return getInnerPosX(mousePos);
12424		else
12425			return getInnerPosY(mousePos);
12426		
12427	}
12428	
12429	
12430	/**
12431	 * move the strip to mouse position on it
12432	 * mousex - mouse position relative to the document
12433	 */
12434	function moveStripToMousePosition(mousePos){		
12435		
12436		var innerPos = getInnerPos(mousePos);
12437		
12438		if(innerPos === null)
12439			return(false);
12440		
12441		g_temp.is_strip_moving = true;
12442		g_temp.strip_finalPos = innerPos;
12443				
12444		startStripMovingLoop();
12445	}
12446	
12447}
12448
12449/**
12450 * slider class
12451 * addon to strip gallery
12452 */
12453function UGSlider(){
12454	
12455	var t = this, g_objThis = jQuery(t);
12456	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objWrapper, g_objThumbs;	
12457	//the video arrows is independent arrows that is not sitting on the controls
12458	var g_objSlider, g_objInner, g_objSlide1, g_objSlide2, g_objSlide3, g_objArrowLeft, g_objArrowRight;
12459	var g_objTouchSlider, g_objZoomSlider, g_objZoomPanel, g_objButtonPlay = null, g_objButtonFullscreen = null, g_objBullets = null;
12460	var g_objVideoPlayer = new UGVideoPlayer(), g_optionsPrefix;
12461	var g_functions = new UGFunctions(), g_objProgress = null, g_objTextPanel = null;
12462	
12463	
12464	this.events = {		
12465		ITEM_CHANGED: "item_changed",				//on item changed
12466		BEFORE_SWITCH_SLIDES: "before_switch",		//before slides switching
12467		BEFORE_RETURN: "before_return",				//before return from pan or from zoom
12468		AFTER_RETURN: "after_return",				//after return from pan or from zoom
12469		ZOOM_START: "slider_zoom_start",			//on zoom start 
12470		ZOOM_END: "slider_zoom_end",				//on zoom move 
12471		ZOOMING: "slider_zooming",					//on zooming
12472		ZOOM_CHANGE: "slider_zoom_change",			//on slide image image zoom change	
12473		START_DRAG: "start_drag",					//on slider drag start
12474		AFTER_DRAG_CHANGE: "after_drag_change",		//after finish drag chagne transition
12475		ACTION_START: "action_start",				//on slide action start
12476		ACTION_END: "action_end",					//on slide action stop
12477		CLICK: "slider_click",						//on click event
12478		TRANSITION_START:"slider_transition_start",	//before transition start event
12479		TRANSITION_END:"slider_transition_end",		//on transition end event
12480		AFTER_PUT_IMAGE: "after_put_image",			//after put slide image
12481		IMAGE_MOUSEENTER: "slider_image_mouseenter", //on slide image mouseonter
12482		IMAGE_MOUSELEAVE: "slider_image_mouseleave",	 		//on slide image mouseleave
12483		CURRENTSLIDE_LOAD_START: "slider_current_loadstart",	//on current slide load image start
12484		CURRENTSLIDE_LOAD_END: "slider_current_loadend"		//on finish load current slide image
12485	}
12486	
12487	var g_options = {
12488		  slider_scale_mode: "fill",					//fit: scale down and up the image to always fit the slider
12489		  												//down: scale down only, smaller images will be shown, don't enlarge images (scale up)
12490		  												//fill: fill the entire slider space by scaling, cropping and centering the image
12491		  												//fitvert: make the image always fill the vertical slider area
12492		  slider_scale_mode_media: "fill",				//fill, fit, down, fitvert - scale mode on media items
12493		  slider_scale_mode_fullscreen: "down",			//fill, fit, down, fitvert - scale mode on fullscreen.
12494		  		  
12495		  slider_item_padding_top: 0,					//padding top of the slider item
12496		  slider_item_padding_bottom: 0,				//padding bottom of the slider item
12497		  slider_item_padding_left: 0,					//padding left of the slider item
12498		  slider_item_padding_right: 0,					//padding right of the slider item
12499		  
12500		  slider_background_color: "",					//slider background color, set if you want to change default
12501		  slider_background_opacity: 1,					//slider background opacity
12502		  
12503		  slider_image_padding_top: 0,					//padding top of the image inside the item
12504		  slider_image_padding_bottom: 0,				//padding bottom of the image inside the item
12505		  slider_image_padding_left: 0,					//padding left of the image inside the item
12506		  slider_image_padding_right: 0,				//padding right of the image inside the item
12507
12508		  slider_image_border: false,					//enable border around the image
12509		  slider_image_border_width: 10,				//image border width
12510		  slider_image_border_color: "#ffffff",			//image border color
12511		  slider_image_border_radius: 0,				//image border radius
12512		  slider_image_border_maxratio: 0.35,			//max ratio that the border can take from the image
12513		  slider_image_shadow: false,					//enable border shadow the image
12514		  
12515		  slider_video_constantsize: false, 			//constant video size mode for video items
12516		  slider_video_constantsize_scalemode: "fit", 	//fit,down: constant video size scale mode
12517		  slider_video_constantsize_width: 854,			//constant video size width
12518		  slider_video_constantsize_height: 480,		//constant video size height
12519		  
12520		  slider_video_padding_top: 0,					//padding top of the video player inside the item
12521		  slider_video_padding_bottom: 0,				//padding bottom of the video player inside the item
12522		  slider_video_padding_left: 0,					//padding left of the video player inside the item
12523		  slider_video_padding_right: 0,				//padding right of the video player inside the item
12524		  
12525		  slider_video_enable_closebutton: true,		//enable video close button
12526		  
12527		  slider_transition: "slide",					//fade, slide - the transition of the slide change
12528		  slider_transition_speed:300,				 	//transition duration of slide change
12529		  slider_transition_easing: "easeInOutQuad",	//transition easing function of slide change
12530		  
12531		  slider_control_swipe:true,					//true,false - enable swiping control
12532		  slider_control_zoom:true,						//true, false - enable zooming control
12533		  slider_zoom_mousewheel: true,					//enable zoom on mousewheel
12534		  slider_vertical_scroll_ondrag: false,			//vertical scroll on slider area drag					  
12535		  slider_loader_type: 1,						//shape of the loader (1-7)
12536		  slider_loader_color:"white",					//color of the loader: (black , white)
12537		  slider_enable_links: true,					//enable slide as link functionality
12538		  slider_links_newpage: false,					//open the slide link in new page
12539		  
12540		  slider_enable_bullets: false,					//enable the bullets onslider element
12541		  slider_bullets_skin: "",						//skin of the bullets, if empty inherit from gallery skin
12542		  slider_bullets_space_between: -1,				//set the space between bullets. If -1 then will be set default space from the skins
12543		  slider_bullets_align_hor:"center",			//left, center, right - bullets horizontal align
12544		  slider_bullets_align_vert:"bottom",			//top, middle, bottom - bullets vertical algin
12545		  slider_bullets_offset_hor:0,					//bullets horizontal offset 
12546		  slider_bullets_offset_vert:10,				//bullets vertical offset
12547		  
12548		  slider_enable_arrows: true,					//enable arrows onslider element
12549		  slider_arrows_skin: "",						//skin of the slider arrows, if empty inherit from gallery skin
12550		  
12551		  slider_arrow_left_align_hor:"left",	  		//left, center, right - left arrow horizonal align
12552		  slider_arrow_left_align_vert:"middle", 		//top, middle, bottom - left arrow vertical align
12553		  slider_arrow_left_offset_hor:20,		  		//left arrow horizontal offset
12554		  slider_arrow_left_offset_vert:0,		  		//left arrow vertical offset
12555		  
12556		  slider_arrow_right_align_hor:"right",   		//left, center, right - right arrow horizontal algin
12557		  slider_arrow_right_align_vert:"middle", 		//top, middle, bottom - right arrow vertical align
12558		  slider_arrow_right_offset_hor:20,	   			//right arrow horizontal offset 
12559		  slider_arrow_right_offset_vert:0,	   			//right arrow vertical offset
12560		  
12561		  slider_enable_progress_indicator: true,		 //enable progress indicator element
12562		  slider_progress_indicator_type: "pie",		 //pie, pie2, bar (if pie not supported, it will switch to bar automatically)
12563		  slider_progress_indicator_align_hor:"right",   //left, center, right - progress indicator horizontal align
12564		  slider_progress_indicator_align_vert:"top",    //top, middle, bottom - progress indicator vertical align
12565		  slider_progress_indicator_offset_hor:10,	     //progress indicator horizontal offset 
12566		  slider_progress_indicator_offset_vert:10,	     //progress indicator vertical offset
12567		  
12568		  slider_enable_play_button: true,				 //true,false - enable play / pause button onslider element
12569		  slider_play_button_skin: "",					 //skin of the slider play button, if empty inherit from gallery skin
12570		  slider_play_button_align_hor:"left",    		 //left, center, right - play button horizontal align
12571		  slider_play_button_align_vert:"top",     		 //top, middle, bottom - play button vertical align
12572		  slider_play_button_offset_hor:40,	       		 //play button horizontal offset 
12573		  slider_play_button_offset_vert:8,	   			 //play button vertical offset
12574		  slider_play_button_mobilehide:false,		 	 //hide the play button on mobile
12575		  
12576		  slider_enable_fullscreen_button: true,		 //true,false - enable fullscreen button onslider element
12577		  slider_fullscreen_button_skin: "",			 //skin of the slider fullscreen button, if empty inherit from gallery skin
12578		  slider_fullscreen_button_align_hor:"left",     //left, center, right	- fullscreen button horizonatal align
12579		  slider_fullscreen_button_align_vert:"top",     //top, middle, bottom - fullscreen button vertical align
12580		  slider_fullscreen_button_offset_hor:11,	     //fullscreen button horizontal offset 
12581		  slider_fullscreen_button_offset_vert:9,	   	 //fullscreen button vertical offset
12582		  slider_fullscreen_button_mobilehide:false,	 //hide the button on mobile
12583		  
12584		  slider_enable_zoom_panel: true,				 //true,false - enable the zoom buttons, works together with zoom control.
12585		  slider_zoompanel_skin: "",					 //skin of the slider zoom panel, if empty inherit from gallery skin		  
12586		  slider_zoompanel_align_hor:"left",    		 //left, center, right - zoom panel horizontal align
12587		  slider_zoompanel_align_vert:"top",     	 	 //top, middle, bottom - zoom panel vertical align
12588		  slider_zoompanel_offset_hor:12,	       		 //zoom panel horizontal offset 
12589		  slider_zoompanel_offset_vert:92,	   			 //zoom panel vertical offset
12590		  slider_zoompanel_mobilehide:false,		     //hide the zoom panel on mobile
12591		  
12592		  slider_controls_always_on: false,				//true,false - controls are always on, false - show only on mouseover
12593		  slider_controls_appear_ontap: true,			//true,false - appear controls on tap event on touch devices
12594		  slider_controls_appear_duration: 300,			//the duration of appearing controls
12595		  
12596		  slider_enable_text_panel: true,				//true,false - enable the text panel
12597		  slider_textpanel_always_on: true,				//true,false - text panel are always on, false - show only on mouseover
12598		  
12599		  slider_videoplay_button_type: "square"		//square, round - the videoplay button type, square or round	
12600	};
12601	
12602	
12603	//default options for bar progress incicator
12604	var g_defaultsProgressBar = {
12605		  slider_progress_indicator_align_hor:"left",    	//left, center, right
12606		  slider_progress_indicator_align_vert:"bottom",    //top, middle, bottom
12607		  slider_progress_indicator_offset_hor:0,	       	//horizontal offset 
12608		  slider_progress_indicator_offset_vert:0	   		//vertical offset
12609	};
12610	
12611	var g_temp = {
12612		isRunOnce: false,
12613		isTextPanelSaparateHover: false,					//if the panel need to be appeared without the controls object on mouseover
12614		numPrev:1,
12615		numCurrent:2,
12616		numNext: 3,
12617		isControlsVisible: true,
12618		currentControlsMode: "image"
12619	};
12620	
12621	function __________GENERAL___________(){};
12622	
12623	
12624	/**
12625	 * init the slider
12626	 */
12627	function initSlider(objGallery, objOptions, optionsPrefix){
12628		g_gallery = objGallery;
12629				
12630		//change options by prefix
12631		if(optionsPrefix){
12632			g_optionsPrefix = optionsPrefix;
12633			objOptions = g_functions.convertCustomPrefixOptions(objOptions, g_optionsPrefix, "slider");
12634		}
12635		
12636		g_objGallery = jQuery(objGallery);
12637		
12638		var objects = g_gallery.getObjects();		
12639		g_objWrapper = objects.g_objWrapper;
12640		g_objThumbs = objects.g_objThumbs;
12641		
12642		//set progress indicator bar defaults if type bar
12643		if(objOptions.hasOwnProperty("slider_progress_indicator_type"))
12644			g_options.slider_progress_indicator_type = objOptions.slider_progress_indicator_type;
12645		
12646		if(g_options.slider_progress_indicator_type == "bar"){
12647			g_options = jQuery.extend(g_options, g_defaultsProgressBar);
12648		}
12649				
12650		if(objOptions)
12651			t.setOptions(objOptions);
12652		
12653		processOptions();
12654		
12655		//init bullets:
12656		if(g_options.slider_enable_bullets == true){
12657			g_objBullets = new UGBullets();
12658			var bulletsOptions = {
12659					bullets_skin: g_options.slider_bullets_skin,
12660					bullets_space_between: g_options.slider_bullets_space_between
12661			}
12662			g_objBullets.init(g_gallery, bulletsOptions);
12663		}
12664		
12665		//init text panel
12666		if(g_options.slider_enable_text_panel){
12667			g_objTextPanel = new UGTextPanel();
12668			g_objTextPanel.init(g_gallery, g_options, "slider");
12669		}
12670		
12671		if(g_options.slider_enable_zoom_panel){
12672			g_objZoomPanel = new UGZoomButtonsPanel();
12673			g_objZoomPanel.init(t, g_options);
12674		}
12675		
12676		var galleryID = g_gallery.getGalleryID();
12677		
12678		//init video player
12679		g_objVideoPlayer.init(g_options, false, galleryID);		
12680	}
12681	
12682	
12683	/**
12684	 * run the slider functionality
12685	 */
12686	function runSlider(){
12687		
12688		if(g_temp.isRunOnce == true)
12689			return(false);
12690		
12691		g_temp.isRunOnce = true;
12692		
12693		//set background color
12694	   if(g_options.slider_background_color){	   		
12695		   var bgColor = g_options.slider_background_color;
12696		   
12697		   if(g_options.slider_background_opacity != 1)
12698			   bgColor = g_functions.convertHexToRGB(bgColor, g_options.slider_background_opacity);
12699		   
12700		   g_objSlider.css("background-color", bgColor);
12701	   
12702	   }else if(g_options.slider_background_opacity != 1){	//set opacity with default color
12703		
12704		   bgColor = g_functions.convertHexToRGB("#000000", g_options.slider_background_opacity);
12705		   g_objSlider.css("background-color", bgColor);
12706	  
12707	   }
12708	   
12709		//init touch slider control
12710		if(g_options.slider_control_swipe == true){
12711			g_objTouchSlider = new UGTouchSliderControl();
12712			g_objTouchSlider.init(t, g_options);
12713		}
12714
12715		//init zoom slider control
12716		if(g_options.slider_control_zoom == true){
12717			g_objZoomSlider = new UGZoomSliderControl();
12718			g_objZoomSlider.init(t, g_options);
12719		}
12720		
12721		//run the text panel
12722		if(g_objTextPanel)
12723			g_objTextPanel.run();
12724		
12725		initEvents();		
12726	}
12727	
12728	
12729	/**
12730	 * process the options
12731	 */
12732	function processOptions(){
12733		var galleryOptions = g_gallery.getOptions();
12734		
12735		//set skins:
12736		var globalSkin = galleryOptions.gallery_skin;
12737		
12738		if(g_options.slider_bullets_skin == "")
12739			g_options.slider_bullets_skin = globalSkin;
12740		
12741		if(g_options.slider_arrows_skin == "")
12742			g_options.slider_arrows_skin = globalSkin;
12743		
12744		if(g_options.slider_zoompanel_skin == "")
12745			g_options.slider_zoompanel_skin = globalSkin;
12746		
12747		if(g_options.slider_play_button_skin == "")
12748			g_options.slider_play_button_skin = globalSkin;
12749		
12750		if(g_options.slider_fullscreen_button_skin == "")
12751			g_options.slider_fullscreen_button_skin = globalSkin;
12752		
12753		g_options.video_enable_closebutton = g_options.slider_video_enable_closebutton;
12754		
12755		//set mousewheel option depends on the gallery option
12756		if(galleryOptions.gallery_mousewheel_role != "zoom")
12757			g_options.slider_zoom_mousewheel = false;
12758	
12759	}
12760	
12761	
12762	/**
12763	 * 
12764	 * get html slide
12765	 */
12766	function getHtmlSlide(loaderClass, numSlide){
12767		
12768		var classVideoplay = "ug-type-square";
12769		if(g_options.slider_videoplay_button_type == "round")
12770			classVideoplay = "ug-type-round";
12771		
12772		var html = "";
12773		html += "<div class='ug-slide-wrapper ug-slide"+numSlide+"'>";
12774		html += "<div class='ug-item-wrapper'></div>";
12775		html += "<div class='ug-slider-preloader "+loaderClass+"'></div>";
12776		html += "<div class='ug-button-videoplay "+classVideoplay+"' style='display:none'></div>";
12777		html += "</div>";
12778		
12779		return(html);
12780	}
12781	
12782	
12783	/**
12784	 * set the slider html
12785	 */
12786	function setHtmlSlider(objParent){
12787		
12788		if(objParent)
12789			g_objWrapper = objParent;
12790		
12791		//get if the slide has controls
12792		var loaderClass = getLoaderClass();
12793		var galleryOptions = g_gallery.getOptions();
12794		
12795		var html = "<div class='ug-slider-wrapper'>";
12796		
12797		html += "<div class='ug-slider-inner'>";
12798		html += getHtmlSlide(loaderClass,1);
12799		html += getHtmlSlide(loaderClass,2);
12800		html += getHtmlSlide(loaderClass,3);
12801				
12802		html += "</div>";	//end inner
12803		
12804		//----------------
12805				
12806		//add arrows
12807		if(g_options.slider_enable_arrows == true){
12808			html += "<div class='ug-slider-control ug-arrow-left ug-skin-"+g_options.slider_arrows_skin+"'></div>";
12809			html += "<div class='ug-slider-control ug-arrow-right ug-skin-"+g_options.slider_arrows_skin+"'></div>";
12810		}
12811		
12812		//add play button
12813		if(g_options.slider_enable_play_button == true){
12814			html += "<div class='ug-slider-control ug-button-play ug-skin-"+g_options.slider_play_button_skin+"'></div>";
12815		}
12816		
12817		//add fullscreen button
12818		if(g_options.slider_enable_fullscreen_button == true){
12819			html += "<div class='ug-slider-control ug-button-fullscreen ug-skin-"+g_options.slider_fullscreen_button_skin+"'></div>";
12820		}
12821		
12822		
12823		html +=	"</div>";	//end slider
12824		
12825		
12826		g_objWrapper.append(html);
12827		
12828		//----------------
12829		
12830		//set objects
12831		g_objSlider = g_objWrapper.children(".ug-slider-wrapper");
12832		g_objInner = g_objSlider.children(".ug-slider-inner");
12833		
12834		
12835		g_objSlide1 = g_objInner.children(".ug-slide1");
12836		g_objSlide2 = g_objInner.children(".ug-slide2");
12837		g_objSlide3 = g_objInner.children(".ug-slide3");
12838		
12839		//set slides data
12840		g_objSlide1.data("slidenum",1);
12841		g_objSlide2.data("slidenum",2);
12842		g_objSlide3.data("slidenum",3);
12843				
12844		//add bullets
12845		if(g_objBullets)
12846			g_objBullets.appendHTML(g_objSlider);
12847		
12848		//----------------
12849		
12850		//get arrows object
12851		if(g_options.slider_enable_arrows == true){
12852			g_objArrowLeft = g_objSlider.children(".ug-arrow-left");
12853			g_objArrowRight = g_objSlider.children(".ug-arrow-right");
12854		}
12855				
12856		//get play button
12857		if(g_options.slider_enable_play_button == true){
12858			g_objButtonPlay = g_objSlider.children(".ug-button-play");
12859		}
12860		
12861		//get fullscreen button
12862		if(g_options.slider_enable_fullscreen_button == true){
12863			g_objButtonFullscreen = g_objSlider.children(".ug-button-fullscreen");
12864		}
12865		
12866		
12867		//----------------
12868		
12869		//add progress indicator
12870		if(g_options.slider_enable_progress_indicator == true){
12871			
12872			g_objProgress = g_functions.initProgressIndicator(g_options.slider_progress_indicator_type, g_options, g_objSlider);
12873			
12874			var finalType = g_objProgress.getType();
12875			
12876			//change options in case of type change
12877			if(finalType == "bar" && g_options.slider_progress_indicator_type == "pie"){
12878				g_options.slider_progress_indicator_type = "bar";
12879				g_options = jQuery.extend(g_options, g_defaultsProgressBar);
12880			}	
12881			
12882			g_gallery.setProgressIndicator(g_objProgress);
12883		}
12884		
12885		//----------------
12886		
12887		//add text panel (hidden)
12888		if(g_options.slider_enable_text_panel == true){
12889			
12890				g_objTextPanel.appendHTML(g_objSlider);
12891								
12892				//hide panel saparatelly from the controls object
12893				if(g_options.slider_textpanel_always_on == false){
12894					
12895					//hide the panel
12896					var panelElement = g_objTextPanel.getElement();
12897					panelElement.hide().data("isHidden", true);
12898	
12899					g_temp.isTextPanelSaparateHover = true;
12900					
12901				}
12902			
12903		}
12904			
12905		//----------------
12906		
12907		//add zoom buttons panel:
12908		if(g_options.slider_enable_zoom_panel == true){
12909			g_objZoomPanel.appendHTML(g_objSlider);
12910		}
12911	
12912		
12913		//add video player
12914		g_objVideoPlayer.setHtml(g_objInner);
12915	}
12916	
12917	
12918	/**
12919	 * position elements that related to slide
12920	 */
12921	function positionSlideElements(objSlide){
12922		
12923		//position preloader
12924		var objPreloader = getSlidePreloader(objSlide);
12925		g_functions.placeElementInParentCenter(objPreloader);
12926		
12927		//position video play button
12928		var objVideoPlayButton = getSlideVideoPlayButton(objSlide);
12929		g_functions.placeElementInParentCenter(objVideoPlayButton);		
12930	}
12931	
12932	
12933	/**
12934	 * position elements
12935	 */
12936	function positionElements(){
12937		
12938		//place bullets
12939		if(g_objBullets){
12940			objBullets = g_objBullets.getElement();
12941			
12942			//strange bug fix (bullets width: 20) by double placing
12943			g_functions.placeElement(objBullets, g_options.slider_bullets_align_hor, g_options.slider_bullets_align_vert, g_options.slider_bullets_offset_hor, g_options.slider_bullets_offset_vert);
12944			g_functions.placeElement(objBullets, g_options.slider_bullets_align_hor, g_options.slider_bullets_align_vert, g_options.slider_bullets_offset_hor, g_options.slider_bullets_offset_vert);
12945			
12946		}
12947		
12948		//place arrows
12949		if(g_options.slider_enable_arrows == true){
12950			g_functions.placeElement(g_objArrowLeft, g_options.slider_arrow_left_align_hor, g_options.slider_arrow_left_align_vert, g_options.slider_arrow_left_offset_hor, g_options.slider_arrow_left_offset_vert);
12951			g_functions.placeElement(g_objArrowRight, g_options.slider_arrow_right_align_hor, g_options.slider_arrow_left_align_vert, g_options.slider_arrow_right_offset_hor, g_options.slider_arrow_right_offset_vert);
12952		}
12953		
12954		//hide controls
12955		if(g_options.slider_controls_always_on == false)
12956			hideControls(true);
12957		
12958		//place progress indicator
12959		if(g_objProgress){
12960			
12961			var objProgressElement = g_objProgress.getElement();
12962			
12963			if(g_options.slider_progress_indicator_type == "bar"){
12964				var sliderWidth = g_objSlider.width();				
12965				g_objProgress.setSize(sliderWidth);
12966				g_functions.placeElement(objProgressElement, "left", g_options.slider_progress_indicator_align_vert, 0, g_options.slider_progress_indicator_offset_vert);				
12967				
12968			}else{
12969				g_functions.placeElement(objProgressElement, g_options.slider_progress_indicator_align_hor, g_options.slider_progress_indicator_align_vert, g_options.slider_progress_indicator_offset_hor, g_options.slider_progress_indicator_offset_vert);				
12970				
12971			}			
12972		}
12973				
12974		//position text panel
12975		if(g_objTextPanel)
12976			g_objTextPanel.positionPanel();
12977		
12978		//position controls elements
12979		placeControlsElements();
12980		
12981		//place slide elements
12982		positionSlideElements(g_objSlide1);
12983		positionSlideElements(g_objSlide2);
12984		positionSlideElements(g_objSlide3);
12985		
12986		checkMobileModify();
12987		
12988	}
12989	
12990	
12991	/**
12992	 * place elements that located on "controls" div
12993	 */
12994	function placeControlsElements(){
12995		
12996		if(g_objButtonPlay)			
12997			g_functions.placeElement(g_objButtonPlay, g_options.slider_play_button_align_hor, g_options.slider_play_button_align_vert, g_options.slider_play_button_offset_hor, g_options.slider_play_button_offset_vert);			
12998		
12999		//position fullscreen button
13000		if(g_objButtonFullscreen)			
13001			g_functions.placeElement(g_objButtonFullscreen, g_options.slider_fullscreen_button_align_hor, g_options.slider_fullscreen_button_align_vert, g_options.slider_fullscreen_button_offset_hor, g_options.slider_fullscreen_button_offset_vert);
13002		
13003		//position zoom panel
13004		if(g_objZoomPanel){
13005			var zoomPanelElement = g_objZoomPanel.getElement();
13006			g_functions.placeElement(zoomPanelElement, g_options.slider_zoompanel_align_hor, g_options.slider_zoompanel_align_vert, g_options.slider_zoompanel_offset_hor, g_options.slider_zoompanel_offset_vert);
13007		}
13008	}
13009	
13010	
13011		
13012	/**
13013	 * position slides by their order
13014	 */
13015	function positionSlides(){
13016		
13017		var slides = t.getSlidesReference();
13018		var posX = 0, posY = 0, innerWidth;
13019		var posXPrev=0, posXCurrent = 0, posXNext, nextHasItem, prevHasItem;
13020				
13021		nextHasItem = t.isSlideHasItem(slides.objNextSlide);
13022		prevHasItem = t.isSlideHasItem(slides.objPrevSlide);
13023		
13024		if(prevHasItem){
13025			posXCurrent = slides.objPrevSlide.outerWidth();
13026			slides.objPrevSlide.css("z-index",1);
13027		}else
13028			slides.objPrevSlide.hide();			
13029		
13030		posXNext = posXCurrent + slides.objCurrentSlide.outerWidth();
13031		
13032		innerWidth = posXNext;
13033		if(nextHasItem){
13034			innerWidth = posXNext + slides.objNextSlide.outerWidth();
13035			slides.objPrevSlide.css("z-index",2);		
13036		}else
13037			slides.objNextSlide.hide();
13038		
13039		slides.objCurrentSlide.css("z-index",3);
13040		
13041		//set inner size and position
13042		g_functions.placeElement(slides.objCurrentSlide, posXCurrent, posY);		
13043		g_objInner.css({"left":-posXCurrent+"px", width:innerWidth+"px"});
13044
13045		//position prev
13046		if(prevHasItem){
13047			g_functions.placeElement(slides.objPrevSlide, posXPrev, posY);
13048			g_functions.showElement(slides.objPrevSlide);
13049		}
13050		
13051		if(nextHasItem){
13052			g_functions.showElement(slides.objNextSlide);
13053			g_functions.placeElement(slides.objNextSlide, posXNext, posY);
13054		}
13055		
13056	}
13057	
13058	
13059	
13060	/**
13061	 * resize the slide image inside item
13062	 */
13063	function resizeSlideItem(objSlide){
13064		var index = objSlide.data("index");
13065		if(index === undefined || index == null)
13066			return(false);
13067		
13068		var objItem = g_gallery.getItem(index);
13069		
13070		if(!objItem)
13071			return(false);
13072		
13073		setItemToSlide(objSlide, objItem);
13074	}
13075	
13076	
13077	/**
13078	 * show the preloader
13079	 * show the index, so only the current index load will hide.
13080	 */	
13081	function showPreloader(objPreloader){
13082		
13083		objPreloader.stop(true).show(100);
13084	
13085	}
13086	
13087	/**
13088	 * hide the preloader
13089	 */
13090	function hidePreloader(objPreloader){
13091		
13092		objPreloader.stop(true).hide(100);
13093	}
13094	
13095	/**
13096	 * get proper image border width
13097	 */
13098	function getImageBorderWidth(objImage, imageData){
13099		
13100		var borderWidth = g_options.slider_image_border_width;
13101		
13102		if(borderWidth <= 10)
13103			return(borderWidth);
13104
13105		//set image size
13106		var imageSize = g_functions.getElementSize(objImage);
13107		var imageWidth = imageSize.width;
13108		var imageHeight = imageSize.height;
13109		
13110		if(imageData){
13111			if(imageData.hasOwnProperty("imageWidth"))
13112				imageWidth = imageData.imageWidth;
13113			
13114			if(imageData.hasOwnProperty("imageHeight"))
13115				imageHeight = imageData.imageHeight;
13116			
13117		}
13118		
13119		if(imageWidth <= 0)
13120			return(borderWidth);
13121		
13122		//take the less size
13123		var totalSize = (imageWidth < imageHeight)?imageWidth:imageHeight;
13124		var borderSize = borderWidth * 2;
13125		
13126		var borderRatio = borderSize / totalSize;
13127		
13128		if(borderRatio < g_options.slider_image_border_maxratio)
13129			return(borderWidth);
13130		
13131		//change border width		
13132		var borderWidth = (totalSize * g_options.slider_image_border_maxratio)/2; 
13133		
13134		borderWidth = Math.round(borderWidth);
13135		
13136		return(borderWidth);
13137		
13138	}
13139	
13140	
13141	/**
13142	 * set slider image css design according the settings
13143	 */
13144	function setImageDesign(objImage, slideType, imageData){
13145		
13146		var css = {};
13147		if(g_options.slider_image_border == true){
13148			css["border-style"] = "solid";
13149			
13150			var borderWidth = getImageBorderWidth(objImage, imageData);
13151			
13152			css["border-width"] = borderWidth+"px";
13153			css["border-color"] = g_options.slider_image_border_color;
13154			css["border-radius"] = g_options.slider_image_border_radius;
13155		}
13156		
13157		if(slideType != "image" && g_options.slider_video_constantsize == true)
13158			css["background-color"] = "#000000";
13159		
13160		if(g_options.slider_image_shadow == true){
13161			css["box-shadow"] = "3px 3px 10px 0px #353535";
13162		}
13163		
13164		objImage.css(css);
13165	}
13166	
13167	
13168	/**
13169	 * scale image constant size (for video items)
13170	 */
13171	function scaleImageConstantSize(objImage, objItem){
13172		
13173		var constantWidth = g_options.slider_video_constantsize_width;
13174		var constantHeight = g_options.slider_video_constantsize_height;
13175		var scaleMode = g_options.slider_video_constantsize_scalemode;
13176		
13177		var objSize = g_functions.scaleImageExactSizeInParent(objImage, objItem.imageWidth, objItem.imageHeight, constantWidth, constantHeight, scaleMode);
13178		
13179		
13180		return(objSize);
13181	}
13182
13183	
13184	/**
13185	 * 
13186	 * set item to slide
13187	 */
13188	function setImageToSlide(objSlide, objItem, isForce){
13189		
13190		var objItemWrapper = objSlide.children(".ug-item-wrapper");
13191		
13192		var objPreloader = getSlidePreloader(objSlide);
13193		
13194		if(typeof objItem.urlImage == "undefined" || objItem.urlImage == "")
13195			throw new Error("The slide don't have big image defined ( data-image='imageurl' ). Please check gallery items.", "showbig");
13196		
13197		var urlImage = objItem.urlImage;
13198		
13199		var currentImage = objSlide.data("urlImage");
13200				
13201		objSlide.data("urlImage",urlImage);
13202		
13203		var scaleMode = t.getScaleMode(objSlide);
13204		
13205		var slideType = t.getSlideType(objSlide);
13206		
13207		objPadding = t.getObjImagePadding();
13208		
13209		
13210		if(currentImage == urlImage && isForce !== true){
13211			
13212			var objImage = objItemWrapper.children("img");
13213						
13214			if(objItem.imageWidth == 0 || objItem.imageHeight == 0){
13215				g_gallery.checkFillImageSize(objImage, objItem);
13216			}
13217			
13218			var objImageData = {};
13219			
13220			if(slideType != "image" && g_options.slider_video_constantsize == true){
13221				objImageData = scaleImageConstantSize(objImage, objItem);
13222			}
13223			else{
13224				objImageData = g_functions.scaleImageFitParent(objImage, objItem.imageWidth, objItem.imageHeight, scaleMode, objPadding);
13225			}
13226			
13227			setImageDesign(objImage, slideType, objImageData);
13228			g_objThis.trigger(t.events.AFTER_PUT_IMAGE, objSlide);
13229			
13230		}
13231		else{		//place the image inside parent first time
13232			
13233			objImage = g_functions.placeImageInsideParent(urlImage, objItemWrapper, objItem.imageWidth, objItem.imageHeight, scaleMode, objPadding);
13234			
13235			//set image loaded on load:
13236			if(objItem.isBigImageLoaded == true){
13237				objImage.fadeTo(0,1);
13238				hidePreloader(objPreloader);
13239				
13240				if(slideType != "image" && g_options.slider_video_constantsize == true)
13241					var objImageData = scaleImageConstantSize(objImage, objItem);
13242				else
13243					var objImageData = g_functions.getImageInsideParentData(objItemWrapper, objItem.imageWidth, objItem.imageHeight, scaleMode, objPadding);
13244				
13245				//set missing css width
13246				objImage.css("width",objImageData.imageWidth+"px");
13247						
13248				setImageDesign(objImage, slideType, objImageData);
13249				
13250				g_objThis.trigger(t.events.AFTER_PUT_IMAGE, objSlide);
13251			}
13252			else{		//if the image not loaded, load the image and show it after.
13253				objImage.fadeTo(0,0);
13254				showPreloader(objPreloader);
13255				objSlide.data("isLoading", true);
13256				
13257				if(t.isSlideCurrent(objSlide))
13258					g_objThis.trigger(t.events.CURRENTSLIDE_LOAD_START);
13259				
13260				objImage.data("itemIndex", objItem.index);
13261				objImage.on("load",function(){
13262					
13263					//place the image normally with coordinates
13264					var objImage = jQuery(this);
13265					var itemIndex = objImage.data("itemIndex");
13266					
13267					objImage.fadeTo(0,1);
13268					
13269					//get and hide preloader
13270					var objSlide = objImage.parent().parent();
13271					var slideType = t.getSlideType(objSlide);
13272					var objPreloader = getSlidePreloader(objSlide);
13273					var objPadding = t.getObjImagePadding();
13274					var scaleMode = t.getScaleMode(objSlide);
13275					
13276					hidePreloader(objPreloader);
13277					objSlide.data("isLoading", false);
13278					
13279					if(t.isSlideCurrent(objSlide))
13280						g_objThis.trigger(t.events.CURRENTSLIDE_LOAD_END);
13281					
13282					g_gallery.onItemBigImageLoaded(null, objImage);
13283					
13284					var objItem = g_gallery.getItem(itemIndex);
13285					
13286					var objImageData = {};
13287					
13288					if(slideType != "image" && g_options.slider_video_constantsize == true)
13289						scaleImageConstantSize(objImage, objItem);
13290					else{
13291						objImageData = g_functions.scaleImageFitParent(objImage, objItem.imageWidth, objItem.imageHeight, scaleMode, objPadding);
13292					}
13293					
13294					objImage.fadeTo(0,1);
13295					
13296					setImageDesign(objImage, slideType, objImageData);
13297					
13298					g_objThis.trigger(t.events.AFTER_PUT_IMAGE, objSlide);
13299				});
13300			}
13301			
13302		}
13303		
13304		
13305	}
13306	
13307		
13308	
13309	/**
13310	 * set slider image by url
13311	 * if item not set, get current slide item
13312	 */
13313	function setItemToSlide(objSlide, objItem){
13314		
13315		try{
13316
13317			var objItemWrapper = objSlide.children(".ug-item-wrapper");
13318					
13319			//if the item is empty, remove the image from slide
13320			if(objItem == null){
13321				objItemWrapper.html("");
13322				objSlide.removeData("index");
13323				objSlide.removeData("type");
13324				objSlide.removeData("urlImage");
13325				return(false);
13326			}
13327			
13328			var currentIndex = objSlide.data("index");
13329			
13330			objSlide.data("index",objItem.index);
13331			objSlide.data("type", objItem.type);
13332			
13333			//set link class
13334			if(g_options.slider_enable_links == true && objItem.type == "image"){
13335				
13336				if(objItem.link)
13337					objSlide.addClass("ug-slide-clickable");
13338				else
13339					objSlide.removeClass("ug-slide-clickable");
13340			}
13341			
13342			setImageToSlide(objSlide, objItem);
13343			
13344			//show type related elements
13345			var objVideoPlayButton = getSlideVideoPlayButton(objSlide);
13346			switch(objItem.type){
13347				case "image":
13348					objVideoPlayButton.hide();
13349				break;
13350				default:		//video
13351					objVideoPlayButton.show();					
13352				break;
13353			}
13354			
13355		}catch(error){
13356			
13357			if(typeof error.fileName != "undefined" && error.fileName == "showbig")
13358				g_gallery.showErrorMessageReplaceGallery(error.message);
13359			
13360			objItemWrapper.html("");
13361			throw new Error(error);
13362			return(true);
13363		}
13364		
13365	}	
13366	
13367	
13368	
13369	/**
13370	 * hide the panel
13371	 */
13372	function hideTextPanel(){
13373		
13374		if(!g_objTextPanel)
13375			return(false);
13376		
13377		if(isTextPanelHidden() == true)
13378			return(false);
13379		
13380		var panelElement = g_objTextPanel.getElement();
13381	
13382		var animationTime = 0;
13383		if(g_temp.isTextPanelSaparateHover == true || g_options.slider_textpanel_always_on == true){
13384			animationTime = g_options.slider_controls_appear_duration;
13385		}
13386		
13387		panelElement.stop().fadeTo(animationTime, 0);
13388		
13389		panelElement.data("isHidden", true);
13390	}
13391	
13392	
13393	/**
13394	 * show the text panel
13395	 */
13396	function showTextPanel(){
13397		
13398		if(!g_objTextPanel)
13399			return(false);
13400		
13401		if(isTextPanelHidden() == false)
13402			return(false);
13403		
13404		var panelElement = g_objTextPanel.getElement();
13405		
13406		var animationTime = 0;
13407		
13408		if(g_temp.isTextPanelSaparateHover == true || g_options.slider_textpanel_always_on == true){
13409			
13410			panelElement.show();
13411			g_objTextPanel.positionElements();
13412			
13413			animationTime = g_options.slider_controls_appear_duration;
13414		}
13415		
13416		panelElement.stop().show().fadeTo(animationTime,1);
13417		
13418		panelElement.data("isHidden", false);
13419				
13420	}
13421	
13422	
13423	/**
13424	 * check if the text panel is hidden or not
13425	 */
13426	function isTextPanelHidden(){
13427
13428		var panelElement = g_objTextPanel.getElement();
13429
13430		var isHidden = panelElement.data("isHidden");
13431		if(isHidden === false)
13432			return(false);
13433		
13434		return(true);		
13435	}	
13436	
13437	
13438	/**
13439	 * validate that the slide is certain type, if not, throw error
13440	 */
13441	function validateSlideType(type, objSlide){
13442		if(objSlide == undefined)
13443			var objSlide = t.getCurrentSlide();
13444		
13445		var slideType = t.getSlideType(objSlide);
13446				
13447		if(slideType != type){
13448			throw new Error("Wrong slide type: "+ slideType +", should be: "+type);
13449			return(false);
13450		}
13451		
13452		return(true);
13453	}
13454	
13455	function __________VIDEO_PLAYER_______(){};
13456
13457	
13458	
13459	/**
13460	 * set video player position
13461	 */
13462	function setVideoPlayerPosition(){
13463		
13464		var objCurrentSlide = t.getCurrentSlide();
13465		var objImage = t.getSlideImage(objCurrentSlide);
13466		
13467		var slideSize = g_functions.getElementSize(objCurrentSlide);
13468		var left = slideSize.left;
13469		var top = slideSize.top;
13470				
13471		//set by image position
13472		if(g_options.slider_video_constantsize == true){
13473			
13474			var imageSize = g_functions.getElementSize(objImage);
13475			left += imageSize.left;
13476			top += imageSize.top;
13477			
13478		}else{	//set video padding
13479			
13480			left += g_options.slider_video_padding_left;
13481			top += g_options.slider_video_padding_top;
13482		
13483		}
13484		
13485		g_objVideoPlayer.setPosition(left, top);
13486	}
13487	
13488	
13489	/**
13490	 * set video player constant size
13491	 */
13492	function setVideoPlayerConstantSize(){
13493		
13494		var videoWidth = g_options.slider_video_constantsize_width;
13495		var videoHeight = g_options.slider_video_constantsize_height;
13496		
13497		g_objVideoPlayer.setSize(videoWidth, videoHeight);
13498		
13499		//set video design
13500		var videoElement = g_objVideoPlayer.getObject();
13501		
13502		setImageDesign(videoElement, "video");
13503	}
13504	
13505	
13506	function __________TRANSITION_______(){};
13507
13508	
13509	
13510	/**
13511	 * do the transition between the current and the next
13512	 */
13513	function doTransition(direction, objItem, forceTransition){
13514		
13515		g_objThis.trigger(t.events.TRANSITION_START);
13516		
13517		var transition = g_options.slider_transition;
13518		if(forceTransition)
13519			transition = forceTransition;
13520
13521		//stop current slide action
13522		t.stopSlideAction(null, true);
13523		
13524		switch(transition){
13525			default:
13526			case "fade":
13527				transitionFade(objItem);
13528			break;
13529			case "slide":				
13530				transitionSlide(direction, objItem);
13531			break;
13532			case "lightbox_open":		//fade transition without animation
13533				transitionFade(objItem, false, true);
13534			break;
13535		}
13536		
13537	}
13538
13539	
13540	/**
13541	 * switch slide numbers after transition (by direction)
13542	 * 
13543	 */
13544	this.switchSlideNums = function(direction){
13545		
13546		//trigger item changed effect
13547		g_objThis.trigger(t.events.BEFORE_SWITCH_SLIDES);
13548		
13549		switch(direction){
13550			case "left":
13551				var currentNum = g_temp.numCurrent;
13552				g_temp.numCurrent = g_temp.numNext;
13553				g_temp.numNext = g_temp.numPrev;
13554				g_temp.numPrev = currentNum;
13555			break;
13556			case "right":
13557				var currentNum = g_temp.numCurrent;
13558				g_temp.numCurrent = g_temp.numPrev;
13559				g_temp.numPrev = g_temp.numNext;
13560				g_temp.numNext = currentNum;				
13561			break;
13562			default:
13563				throw new Error("wrong direction: "+ direction);
13564			break;
13565		}
13566		
13567		//trace(g_temp.numCurrent);
13568		
13569		//trigger item changed effect
13570		g_objThis.trigger(t.events.ITEM_CHANGED);
13571	}
13572	
13573	
13574	/**
13575	 * do slide transition
13576	 */
13577	function transitionSlide(direction, objItem){
13578		
13579		var animating = t.isAnimating();
13580
13581		if(animating == true){
13582			g_temp.itemWaiting = objItem;
13583			return(true);
13584		}
13585		
13586		//always clear next item on transition start
13587		// next item can be only in the middle of the transition.
13588		if(g_temp.itemWaiting != null)
13589			g_temp.itemWaiting = null;
13590		
13591		var slides = t.getSlidesReference();
13592		
13593		
13594		switch(direction){
13595			case "right":	//change to prev item
13596				setItemToSlide(slides.objPrevSlide, objItem);
13597				positionSlides();
13598				
13599				var posPrev = g_functions.getElementSize(slides.objPrevSlide);
13600				var destX = -posPrev.left;
13601				
13602				t.switchSlideNums("right");
13603				
13604			break;	
13605			case "left":		//change to next item
13606				setItemToSlide(slides.objNextSlide, objItem);
13607				positionSlides();
13608				
13609				var posNext = g_functions.getElementSize(slides.objNextSlide);
13610				var destX = -posNext.left;
13611				
13612				t.switchSlideNums("left");
13613				
13614			break;
13615			default:
13616				throw new Error("wrong direction: "+direction);
13617			break;
13618		}
13619				
13620		var transSpeed = g_options.slider_transition_speed;
13621		var transEasing = g_options.slider_transition_easing;
13622
13623		
13624		var animateParams = {
13625				duration: transSpeed,
13626				easing: transEasing,
13627				queue: false,
13628				always:function(){
13629						
13630						t.stopSlideAction();
13631						g_objVideoPlayer.hide();
13632						
13633						//transit next item if waiting
13634						if(g_temp.itemWaiting != null){
13635							var direction = getSlideDirection(g_temp.itemWaiting);
13636							transitionSlide(direction, g_temp.itemWaiting);
13637						}else{
13638							//if no item waiting, please neighbour items in places
13639							t.placeNabourItems();
13640							g_objThis.trigger(t.events.TRANSITION_END);
13641						}
13642					
13643				}
13644		};
13645		
13646		
13647		g_objInner.animate({left:destX+"px"}, animateParams);
13648			
13649	}
13650	
13651	
13652	/**
13653	 * 
13654	 * animate opacity in and out
13655	 */
13656	function animateOpacity(objItem, opacity, completeFunction){
13657		
13658		if(completeFunction)
13659			objItem.fadeTo(g_options.slider_transition_speed, opacity, completeFunction);
13660		else
13661			objItem.fadeTo(g_options.slider_transition_speed, opacity);
13662	}
13663	
13664	
13665	/**
13666	 * do fade transition
13667	 */
13668	function transitionFade(objItem, noAnimation, noHidePlayer){
13669		
13670		if(!noAnimation)
13671			var noAnimation = false;
13672		
13673		var slides = t.getSlidesReference();
13674		 
13675		setItemToSlide(slides.objNextSlide, objItem);
13676		
13677		var objCurrentPos = g_functions.getElementSize(slides.objCurrentSlide);
13678				
13679		g_functions.placeElement(slides.objNextSlide,objCurrentPos.left,objCurrentPos.top);
13680		
13681		//switch slide nums
13682		var currentNum = g_temp.numCurrent;
13683		g_temp.numCurrent = g_temp.numNext;
13684		g_temp.numNext = currentNum;
13685		
13686		g_objThis.trigger(t.events.ITEM_CHANGED);
13687		
13688		slides.objNextSlide.stop(true);		
13689		slides.objCurrentSlide.stop(true);
13690		
13691		if(noAnimation == true){
13692			
13693			slides.objCurrentSlide.fadeTo(0, 0);
13694			slides.objNextSlide.fadeTo(0, 1);	
13695			t.placeNabourItems();
13696			g_objThis.trigger(t.events.TRANSITION_END);
13697			
13698			if(noHidePlayer !== true)
13699				g_objVideoPlayer.hide();
13700		
13701		}else{
13702			slides.objNextSlide.fadeTo(0,0);	
13703			
13704			animateOpacity(slides.objCurrentSlide,0,function(){
13705				t.placeNabourItems();
13706				g_objThis.trigger(t.events.TRANSITION_END);
13707				if(noHidePlayer !== true)
13708					g_objVideoPlayer.hide();
13709			});
13710			
13711			if(g_objVideoPlayer.isVisible() == true){
13712				var videoElement = g_objVideoPlayer.getObject();
13713				animateOpacity(videoElement, 0);
13714			}
13715			
13716			//animate to next show next
13717			animateOpacity(slides.objNextSlide,1);			
13718		}
13719		
13720	}
13721	
13722	
13723	
13724	
13725	function __________CONTROLS_OBJECT_______(){};
13726	
13727	/**
13728	 * modify the slider for mobile
13729	 */
13730	function modifyForMobile(){
13731		
13732		if(g_options.slider_fullscreen_button_mobilehide == true && g_objButtonFullscreen)
13733			g_objButtonFullscreen.hide();
13734		
13735		if(g_options.slider_play_button_mobilehide == true && g_objButtonPlay)
13736			g_objButtonPlay.hide();
13737		
13738		if(g_options.slider_zoompanel_mobilehide == true && g_objZoomPanel)
13739			g_objZoomPanel.getElement().hide();
13740		
13741	}
13742	
13743	
13744	/**
13745	 * modify for no mobile
13746	 */
13747	function modifyForDesctop(){
13748		
13749		if(g_options.slider_fullscreen_button_mobilehide == true && g_objButtonFullscreen)
13750			g_objButtonFullscreen.show();
13751
13752		if(g_options.slider_play_button_mobilehide == true && g_objButtonPlay)
13753			g_objButtonPlay.show();
13754		
13755		if(g_options.slider_zoompanel_mobilehide == true && g_objZoomPanel)
13756			g_objZoomPanel.getElement().show();
13757		
13758	}
13759	
13760	
13761	/**
13762	 * check and modify for mobile or desctop
13763	 */
13764	function checkMobileModify(){
13765		
13766		var isMobile = g_gallery.isMobileMode();
13767		
13768		if(isMobile)
13769			modifyForMobile();
13770		else
13771			modifyForDesctop();
13772				
13773	}
13774	
13775	
13776	/**
13777	 * get a jquery set of the controls objects
13778	 */
13779	function getControlsObjects(){
13780		
13781		var objControl = g_objSlider.children(".ug-slider-control");
13782		
13783		return(objControl);
13784	}
13785	
13786	
13787	/**
13788	 * hide the controls
13789	 */
13790	function hideControls(noAnimation){
13791				
13792		if(g_functions.isTimePassed("sliderControlsToggle") == false)
13793			return(false);
13794		
13795		if(g_temp.isControlsVisible == false)
13796			return(false);
13797				
13798		if(!noAnimation)
13799			var noAnimation = false;
13800		
13801		var objControls = getControlsObjects();
13802		
13803		if(noAnimation === true)
13804			objControls.stop().fadeTo(0,0).hide();
13805		else{
13806			objControls.stop().fadeTo(g_options.slider_controls_appear_duration, 0, function(){objControls.hide()});
13807		}
13808		
13809		g_temp.isControlsVisible = false;
13810	}
13811	
13812	
13813	/**
13814	 * show controls only if they meaned to be shown
13815	 * @param noAnimation
13816	 */
13817	function checkAndShowControls(noAnimation){
13818		
13819		if(g_options.slider_controls_always_on == true)
13820			showControls(noAnimation);		
13821	}
13822	
13823	
13824	/**
13825	 * hide the controls
13826	 */
13827	function showControls(noAnimation){
13828				
13829		//validate for short time pass
13830		if(g_functions.isTimePassed("sliderControlsToggle") == false)
13831			return(false);
13832		
13833		if(g_temp.isControlsVisible == true)
13834			return(true);
13835		
13836		
13837		if(!noAnimation)
13838			var noAnimation = false;
13839		
13840		var objControls = getControlsObjects();
13841				
13842		if(noAnimation === true)
13843			objControls.stop().show();
13844		else{
13845		
13846			objControls.stop().show().fadeTo(0,0);
13847			objControls.fadeTo(g_options.slider_controls_appear_duration, 1);
13848			
13849		}
13850		
13851		g_temp.isControlsVisible = true;
13852		
13853	}
13854	
13855	
13856	
13857	/**
13858	 * toggle the controls (show, hide)
13859	 */
13860	function toggleControls(){
13861								
13862		if(g_temp.isControlsVisible == false)
13863			showControls();
13864		else
13865			hideControls();
13866	}
13867	
13868	
13869	/**
13870	 * set controls mode
13871	 * modes: image, video
13872	 */
13873	function setControlsMode(mode){
13874				
13875		if(mode == g_temp.currentControlsMode)
13876			return(false);
13877		
13878		switch(mode){
13879			case "image":
13880				if(g_objZoomPanel)
13881					g_objZoomPanel.getElement().show();			
13882			break;
13883			case "video":
13884				if(g_objZoomPanel)
13885					g_objZoomPanel.getElement().hide();	
13886			break;
13887			default:
13888				throw new Error("wrong controld mode: " + mode);
13889			break;
13890		}
13891		
13892		g_temp.currentControlsMode = mode;
13893			
13894	}
13895	
13896	
13897	
13898	function __________EVENTS___________(){};
13899
13900	/**
13901	 * on item change event
13902	 */
13903	function onItemChange(data, arg_objItem, role){
13904		
13905		//trace("slider on change");
13906		
13907		var objItem = g_gallery.getSelectedItem();
13908				
13909		t.setItem(objItem, false, role);
13910		
13911		var itemIndex = objItem.index;
13912		
13913		//set active bullet
13914		if(g_objBullets)
13915			g_objBullets.setActive(itemIndex);
13916		
13917		//handle text panel
13918		if(g_objTextPanel){			
13919			if(g_temp.isTextPanelSaparateHover == false)
13920				showTextPanel();
13921		}
13922				
13923		if(objItem.type == "image"){
13924			setControlsMode("image");
13925			//placeControlsElements();
13926		}
13927		else{
13928			setControlsMode("video");
13929		}
13930				
13931	}
13932	
13933	
13934	/**
13935	 * on bullet click - change the item to selected
13936	 */
13937	function onBulletClick(event, bulletIndex){
13938		g_gallery.selectItem(bulletIndex);		
13939	}
13940	
13941	
13942	/**
13943	 * on touch end
13944	 * toggle controls
13945	 */
13946	function onClick(event){
13947		
13948		//double tap action
13949		if(g_objTouchSlider && g_objTouchSlider.isTapEventOccured(event) == false)
13950			return(true);
13951		
13952		g_objThis.trigger(t.events.CLICK, event);
13953			
13954		
13955	}
13956
13957	
13958	/**
13959	 * on actual click event
13960	 */
13961	function onActualClick(){
13962
13963		//check link
13964		var currentSlide = t.getCurrentSlide();
13965		var isClickable = currentSlide.hasClass("ug-slide-clickable");
13966		var objItem = t.getCurrentItem();
13967		
13968		if(isClickable){
13969			
13970			//redirect to link
13971			if(g_options.slider_links_newpage == false){
13972				location.href = objItem.link;
13973			}else{
13974				window.open(objItem.link, '_blank');			
13975			}
13976			
13977			return(true);
13978		}
13979		
13980		//check toggle controls
13981		if(g_options.slider_controls_always_on == false && 
13982		   g_options.slider_controls_appear_ontap == true && t.isCurrentSlideType("image") == true){
13983			
13984			toggleControls();
13985			
13986			//show text panel if hidden
13987			if(g_objTextPanel && g_options.slider_textpanel_always_on == true && t.isCurrentSlideType("image") && t.isCurrentSlideImageFit())
13988				showTextPanel();
13989		}
13990		
13991		
13992	}
13993	
13994	
13995	/**
13996	 * on zoom start event
13997	 */
13998	function onZoomChange(event){
13999		
14000		if(g_objTextPanel && t.isCurrentSlideType("image") && t.isCurrentSlideImageFit() == false)
14001			hideTextPanel();
14002	}
14003	
14004	
14005	/**
14006	 * on mouse enter
14007	 */
14008	function onMouseEnter(){
14009		
14010		showControls();
14011	
14012	}
14013	
14014	
14015	/**
14016	 * on mouse leave
14017	 */
14018	function onMouseLeave(){
14019
14020		hideControls();
14021		
14022	}
14023	
14024	
14025	/**
14026	 * on slide video play button click
14027	 */
14028	function objVideoPlayClick(objButton){
14029		var objSlide = objButton.parent();
14030		t.startSlideAction(objSlide);
14031	}
14032
14033	/**
14034	 * on video player show event
14035	 */
14036	function onVideoPlayerShow(){
14037		
14038		if(g_gallery.isPlayMode()){
14039			g_gallery.pausePlaying();
14040		}
14041		
14042		g_objThis.trigger(t.events.ACTION_START);
14043	}
14044	
14045	
14046	/**
14047	 * on video player hide event
14048	 */
14049	function onVideoPlayerHide(){
14050		
14051		if(g_gallery.isPlayMode()){
14052			g_gallery.continuePlaying();
14053		}
14054		
14055		g_objThis.trigger(t.events.ACTION_END);		
14056	}
14057	
14058	
14059	/**
14060	 * on item image update, update the image inside the slider if relevant
14061	 */
14062	function onItemImageUpdate(event, index, urlImage){
14063				
14064		if(g_objSlide1.data("index") == index){
14065			objItem = g_gallery.getItem(index);
14066			setImageToSlide(g_objSlide1, objItem, true);	//force
14067		}
14068		
14069		if(g_objSlide2.data("index") == index){
14070			objItem = g_gallery.getItem(index);
14071			setImageToSlide(g_objSlide2, objItem, true);
14072		}
14073		
14074		if(g_objSlide3.data("index") == index){
14075			objItem = g_gallery.getItem(index);
14076			setImageToSlide(g_objSlide3, objItem, true);
14077		}
14078		
14079	}
14080	
14081	
14082	/**
14083	 * after image loaded. position video play button
14084	 */
14085	function onSlideImageLoaded(data, objSlide){
14086		
14087		objSlide = jQuery(objSlide);
14088		var objImage = t.getSlideImage(objSlide);
14089		var objButtonVideoPlay = getSlideVideoPlayButton(objSlide);
14090		var objSize = g_functions.getElementSize(objImage);
14091		
14092		g_functions.placeElement(objButtonVideoPlay, "center", "middle", objSize.left, objSize.top, objImage);
14093	}
14094	
14095	
14096	/**
14097	 * init event of current slide
14098	 */
14099	function initSlideEvents(objSlide){
14100		
14101		//set video player events
14102		var objVideoPlayButton = getSlideVideoPlayButton(objSlide);
14103		g_functions.addClassOnHover(objVideoPlayButton);
14104		
14105		g_functions.setButtonOnClick(objVideoPlayButton, objVideoPlayClick);
14106		
14107	}
14108	
14109	
14110	/**
14111	 * init events
14112	 */
14113	function initEvents(){
14114		
14115		//on item image update, update the image inside the slider if relevant
14116		g_objGallery.on(g_gallery.events.ITEM_IMAGE_UPDATED, onItemImageUpdate);
14117		
14118		
14119		//on item change, change the item in the slider.
14120		g_objGallery.on(g_gallery.events.ITEM_CHANGE, onItemChange);
14121		
14122		if(g_objBullets)
14123			jQuery(g_objBullets).on(g_objBullets.events.BULLET_CLICK,onBulletClick);
14124		
14125		//arrows events
14126		if(g_options.slider_enable_arrows == true){
14127			
14128			g_functions.addClassOnHover(g_objArrowRight, "ug-arrow-hover");
14129			g_functions.addClassOnHover(g_objArrowLeft, "ug-arrow-hover");
14130			
14131			g_gallery.setNextButton(g_objArrowRight);
14132			g_gallery.setPrevButton(g_objArrowLeft);
14133		}
14134		
14135		
14136		//show / hide controls
14137		if(g_options.slider_controls_always_on == false){
14138			
14139			//assign hover evens only if no touch device
14140			g_objSlider.hover(onMouseEnter, onMouseLeave);
14141			
14142		}
14143		
14144		//touch events appear on tap event
14145		g_objSlider.on("touchend click", onClick);
14146		
14147		//actual click event
14148		g_objThis.on(t.events.CLICK, onActualClick);
14149		
14150		//show / hide text panel, if it's saparate from controls
14151		if(g_objTextPanel && g_temp.isTextPanelSaparateHover == true){
14152			g_objSlider.hover(showTextPanel, hideTextPanel);
14153		}
14154		
14155		//init play / pause button
14156		if(g_objButtonPlay){
14157			g_functions.addClassOnHover(g_objButtonPlay, "ug-button-hover");
14158			g_gallery.setPlayButton(g_objButtonPlay);
14159		}
14160		
14161		//init fullscreen button
14162		if(g_objButtonFullscreen){
14163			g_functions.addClassOnHover(g_objButtonFullscreen, "ug-button-hover");
14164			g_gallery.setFullScreenToggleButton(g_objButtonFullscreen);
14165		}
14166		
14167		//on zoom start / end events
14168		if(g_objZoomSlider){
14169			g_objThis.on(t.events.ZOOM_CHANGE, onZoomChange);
14170		}
14171		
14172		if(g_objZoomPanel)
14173			g_objZoomPanel.initEvents();
14174				
14175		//init video player related events
14176		g_objVideoPlayer.initEvents();
14177		
14178		//video API events
14179		jQuery(g_objVideoPlayer).on(g_objVideoPlayer.events.SHOW, onVideoPlayerShow);		
14180		jQuery(g_objVideoPlayer).on(g_objVideoPlayer.events.HIDE, onVideoPlayerHide);
14181		
14182		//add slide events
14183		initSlideEvents(g_objSlide1);
14184		initSlideEvents(g_objSlide2);
14185		initSlideEvents(g_objSlide3);
14186		
14187		//on image loaded
14188		g_objThis.on(t.events.AFTER_PUT_IMAGE, onSlideImageLoaded);
14189		
14190		//image mouseenter / mouseleave event
14191		
14192		//set mouseover events on the images
14193		g_objSlider.on("mouseenter",".ug-item-wrapper img",function(event){
14194			g_objThis.trigger(t.events.IMAGE_MOUSEENTER);
14195		});
14196		
14197		g_objSlider.on("mouseleave",".ug-item-wrapper img",function(event){
14198			var isMouseOver = t.isMouseInsideSlideImage(event);
14199			
14200			if(isMouseOver == false)
14201				g_objThis.trigger(t.events.IMAGE_MOUSELEAVE);
14202		});
14203		
14204	}
14205	
14206	
14207	/**
14208	 * destroy slider events
14209	 */
14210	this.destroy = function(){
14211		
14212		g_objThis.off(t.events.AFTER_PUT_IMAGE);
14213				
14214		g_objGallery.off(g_gallery.events.ITEM_IMAGE_UPDATED);
14215		g_objGallery.off(g_gallery.events.ITEM_CHANGE);
14216		
14217		if(g_objBullets)
14218			jQuery(g_objBullets).on(g_objBullets.events.BULLET_CLICK);
14219		
14220		g_objSlider.off("mouseenter");
14221		g_objSlider.off("mouseleave");
14222		
14223		g_objSlider.off("touchend");
14224		g_objSlider.off("click");
14225		g_objThis.off(t.events.CLICK);
14226		
14227		if(g_objZoomSlider)
14228			g_objThis.off(t.events.ZOOM_CHANGE);
14229		
14230		g_objThis.off(t.events.BEFORE_SWITCH_SLIDES);
14231		jQuery(g_objVideoPlayer).off(g_objVideoPlayer.events.SHOW);		
14232		jQuery(g_objVideoPlayer).off(g_objVideoPlayer.events.HIDE);
14233		
14234		g_objVideoPlayer.destroy();
14235		
14236		g_objSlider.off("mouseenter",".ug-item-wrapper img");
14237		g_objSlider.off("mouseleave",".ug-item-wrapper img");
14238	}
14239	
14240	
14241	function __________GETTERS___________(){};
14242	
14243	/**
14244	 * get loader class by loader type
14245	 */
14246	function getLoaderClass(){
14247		var loaderClass;
14248		switch(g_options.slider_loader_type){
14249			default:
14250			case 1: loaderClass = "ug-loader1";break;
14251			case 2: loaderClass = "ug-loader2";break;
14252			case 3: loaderClass = "ug-loader3";break;
14253			case 4: loaderClass = "ug-loader4";break;
14254			case 5: loaderClass = "ug-loader5";break;
14255			case 6: loaderClass = "ug-loader6";break;
14256			case 7: loaderClass = "ug-loader7";break;
14257			case 8: loaderClass = "ug-loader8";break;
14258			case 9: loaderClass = "ug-loader9";break;
14259		}
14260				
14261		if(g_options.slider_loader_color == "black")
14262			loaderClass += " ug-loader-black";
14263		
14264		return(loaderClass);
14265	}
14266	
14267	
14268	
14269	/**
14270	 * 
14271	 * get slide by number
14272	 */
14273	function getSlideByNum(num){
14274				
14275		switch(num){
14276			case 1:
14277				return(g_objSlide1);
14278			break;
14279			case 2:
14280				return(g_objSlide2);
14281			break;
14282			case 3:
14283				return(g_objSlide3);
14284			break;
14285			default:
14286				throw new Error("wrong num: " + num);
14287			break;
14288		}
14289	}
14290	
14291	
14292	/**
14293	 * 
14294	 * get slide direction of current item
14295	 */
14296	function getSlideDirection(objItem){
14297		
14298		var slides = t.getSlidesReference();
14299		
14300		//validate if the item is not selected already
14301		var currentIndex = slides.objCurrentSlide.data("index");
14302		var nextIndex = objItem.index;
14303		
14304		var direction = "left";
14305		if(currentIndex > nextIndex)
14306			direction = "right";
14307				
14308		return(direction);
14309	}
14310	
14311	
14312	/**
14313	 * get slide preloader
14314	 */
14315	function getSlidePreloader(objSlide){
14316		
14317		if(!objSlide)
14318			var objSlide = t.getCurrentSlide();
14319		
14320		var objPreloader = objSlide.children(".ug-slider-preloader");
14321		return(objPreloader);
14322	}
14323	
14324	/**
14325	 * get slide videoplay button
14326	 */
14327	function getSlideVideoPlayButton(objSlide){
14328		var objButton = objSlide.children(".ug-button-videoplay");
14329		return(objButton);
14330	}
14331	
14332	
14333	
14334	/**
14335	 * get slide item
14336	 */
14337	function getSlideItem(objSlide){
14338		if(!objSlide)
14339			var objSlide = t.getCurrentSlide();
14340			
14341		var index = objSlide.data("index");
14342		if(index == undefined)
14343			return(null);
14344		
14345		var objItem = g_gallery.getItem(index);
14346		return(objItem);
14347	}
14348	
14349	
14350	/**
14351	 * get slide number
14352	 */
14353	function getNumSlide(objSlide){
14354		var numSlide = objSlide.data("slidenum");
14355		return(numSlide);
14356	}
14357	
14358	
14359	
14360	this.________EXTERNAL_GENERAL___________ = function(){};
14361	
14362	
14363	/**
14364	 * init function for avia controls
14365	 * options: width / height
14366	 */
14367	this.init = function(objGallery, objOptions, optionsPrefix){
14368				
14369		initSlider(objGallery, objOptions, optionsPrefix);
14370	}
14371
14372	/**
14373	 * get slide image
14374	 */
14375	this.getSlideImage = function(objSlide){
14376		
14377		if(!objSlide)
14378			var objSlide = t.getCurrentSlide();
14379		
14380		var objImage = objSlide.find(".ug-item-wrapper img");
14381		return(objImage);
14382	}
14383	
14384	
14385	/**
14386	 * set slider html
14387	 */
14388	this.setHtml = function(objParent){
14389		
14390		setHtmlSlider(objParent);
14391	}
14392	
14393	
14394	/**
14395	 * run the slider
14396	 */
14397	this.run = function(){
14398		
14399		runSlider();
14400	}
14401	
14402	
14403	/**
14404	 * check if the inner object in place, for panning znd zooming posibility check
14405	 */
14406	this.isInnerInPlace = function(){
14407		
14408		var slides = t.getSlidesReference();
14409		
14410		var posCurrent = g_functions.getElementSize(slides.objCurrentSlide);
14411		var inPlaceX = -posCurrent.left;
14412		var objInnerSize = g_functions.getElementSize(g_objInner);
14413		
14414		if(inPlaceX == objInnerSize.left)
14415			return(true);
14416		else
14417			return(false);
14418	}
14419	
14420	/**
14421	 * is animating
14422	 */
14423	this.isAnimating = function(){
14424		
14425		var isAnimated = g_objInner.is(":animated");
14426		
14427		return(isAnimated);
14428	}
14429	
14430	/**
14431	 * check if the slide is current
14432	 */
14433	this.isSlideCurrent = function(objSlide){
14434		var numSlide = objSlide.data("slidenum");
14435		if(g_temp.numCurrent == numSlide)
14436			return(true);
14437		
14438		return(false);
14439	}
14440	
14441	
14442	/**
14443	 * 
14444	 * tells if the slide has item
14445	 */
14446	this.isSlideHasItem = function(objSlide){
14447		var index = objSlide.data("index");
14448		if(index === undefined || index === null)
14449			return(false);
14450		
14451		return(true);
14452	}
14453	
14454	
14455	/**
14456	 * get image padding object for scaling the image
14457	 */
14458	this.getObjImagePadding = function(){
14459		
14460		var objPadding = {
14461				padding_top: g_options.slider_image_padding_top,
14462				padding_bottom: g_options.slider_image_padding_bottom,
14463				padding_left: g_options.slider_image_padding_left,
14464				padding_right: g_options.slider_image_padding_right
14465		};
14466		
14467		return(objPadding);
14468	}
14469			
14470	
14471	/**
14472	 * get items reference by their order
14473	 */
14474	this.getSlidesReference = function(){
14475		
14476		var obj = {
14477				objPrevSlide: getSlideByNum(g_temp.numPrev),
14478				objNextSlide: getSlideByNum(g_temp.numNext),
14479				objCurrentSlide: getSlideByNum(g_temp.numCurrent)
14480		};
14481		
14482		return(obj);
14483	}
14484	
14485	
14486	/**
14487	 * get current slide
14488	 */
14489	this.getCurrentSlide = function(){
14490		
14491		var slides = t.getSlidesReference();
14492		
14493		return(slides.objCurrentSlide);
14494	}
14495	
14496	
14497	/**
14498	 * get index of current item
14499	 */
14500	this.getCurrentItemIndex = function(){
14501		
14502		var slides = t.getSlidesReference();
14503		
14504		var currentIndex = slides.objCurrentSlide.data("index");
14505		if(currentIndex === null || currentIndex === undefined)
14506			currentIndex = -1;
14507		
14508		return(currentIndex);
14509	}
14510	
14511	
14512	/**
14513	 * get current slide item
14514	 */
14515	this.getCurrentItem = function(){
14516		var currentIndex = t.getCurrentItemIndex();
14517		if(currentIndex == -1)
14518			return(null);
14519		
14520		var objItem = g_gallery.getItem(currentIndex);
14521		
14522		return(objItem);
14523	}
14524		
14525	
14526	/**
14527	 * get type of some slide
14528	 */
14529	this.getSlideType = function(objSlide){
14530		
14531		if(objSlide == undefined)
14532			objSlide = t.getCurrentSlide();
14533			
14534		var type = objSlide.data("type");
14535		return(type);		
14536	}
14537
14538	
14539	/**
14540	 * is mouse inside slide image
14541	 * get mouse position from event
14542	 */
14543	this.isMouseInsideSlideImage = function(event){
14544		
14545		var objImage = t.getSlideImage();
14546		
14547		var point = g_functions.getMousePosition(event);
14548		if(point.pageX === undefined)
14549			point = g_objTouchSlider.getLastMousePos();
14550		
14551		var pointImg = g_functions.getMouseElementPoint(point, objImage);
14552		var objSize = g_functions.getElementSize(objImage);
14553		isMouseInside = g_functions.isPointInsideElement(pointImg, objSize);
14554		
14555		return(isMouseInside);
14556	}
14557	
14558	
14559	/**
14560	 * check if current slide type is certain type
14561	 */
14562	this.isCurrentSlideType = function(type){
14563		var currentSlideType = t.getSlideType();
14564		if(currentSlideType == type)
14565			return(true);
14566		
14567		return(false);
14568	}
14569	
14570	
14571	/**
14572	 * check if current slide is loading image
14573	 */
14574	this.isCurrentSlideLoadingImage = function(){
14575		var currentSlide = t.getCurrentSlide();
14576		var isLoading = currentSlide.data("isLoading");
14577		if(isLoading === true)
14578			return(true);
14579		
14580		return(false);
14581	}
14582	
14583	
14584	/**
14585	 * change the slider to some item content
14586	 */
14587	this.setItem = function(objItem, forseTransition, role){
14588		
14589		var slides = t.getSlidesReference();
14590		
14591		//validate if the item is not selected already
14592		var currentIndex = slides.objCurrentSlide.data("index");
14593		var nextIndex = objItem.index;
14594		
14595		if(nextIndex == currentIndex){
14596			return(true);
14597		}
14598		
14599		var isFirstSlide = (currentIndex == undefined);
14600		
14601		if(isFirstSlide){			
14602			setItemToSlide(slides.objCurrentSlide, objItem);
14603			t.placeNabourItems();
14604			
14605		}else{
14606			
14607			var direction = "left";		//move foreward
14608			
14609			var numItems = g_gallery.getNumItems();
14610			
14611			if(role == "next")
14612				direction = "left";
14613			else if(role == "prev" || currentIndex > nextIndex)
14614				direction = "right";
14615			else if(currentIndex > nextIndex)
14616					direction = "right";
14617						
14618			doTransition(direction, objItem, forseTransition);
14619		}
14620					
14621	}
14622	
14623	
14624	/**
14625	 * when the transition complete, put the next / prev items at their place
14626	 */
14627	this.placeNabourItems = function(){
14628				
14629		var slides = t.getSlidesReference();
14630		var currentIndex = slides.objCurrentSlide.data("index");
14631				
14632		var itemPrev = g_gallery.getPrevItem(currentIndex);
14633		var itemNext = g_gallery.getNextItem(currentIndex);
14634		
14635		//trace(itemPrev);
14636		//trace(itemNext);
14637		
14638		//trace("place " + currentIndex, "next: "+);
14639		
14640		setItemToSlide(slides.objNextSlide, itemNext);
14641		setItemToSlide(slides.objPrevSlide, itemPrev);
14642		
14643		positionSlides();
14644	}
14645	
14646	
14647	
14648	this.________EXTERNAL_API___________ = function(){};
14649	
14650	
14651	/**
14652	 * stop some slide action if active
14653	 */
14654	this.stopSlideAction = function(objSlide, isPause){
14655		
14656		if(!objSlide)
14657			objSlide = t.getCurrentSlide();
14658		
14659		if(isPause === true)
14660			g_objVideoPlayer.pause();
14661		else
14662			g_objVideoPlayer.hide();
14663		
14664	//	trace("stop action");
14665		
14666	}
14667	
14668	
14669	
14670	/**
14671	 * start some slide action if exists
14672	 */
14673	this.startSlideAction = function(objSlide){
14674		
14675	//	trace("start action");
14676		
14677		if(!objSlide)
14678			objSlide = t.getCurrentSlide();
14679		
14680		var objItem = getSlideItem(objSlide);
14681		
14682		if(objItem.type == "image")
14683			return(true)
14684		
14685		if(g_options.slider_video_constantsize == true)
14686			setVideoPlayerConstantSize();
14687		
14688		setVideoPlayerPosition();
14689		
14690		g_objVideoPlayer.show();
14691		
14692		switch(objItem.type){
14693			case "youtube":
14694				g_objVideoPlayer.playYoutube(objItem.videoid);
14695			break;
14696			case "vimeo":
14697				g_objVideoPlayer.playVimeo(objItem.videoid);
14698			break;
14699			case "html5video":
14700				g_objVideoPlayer.playHtml5Video(objItem.videoogv, objItem.videowebm, objItem.videomp4, objItem.urlImage);
14701			break;
14702			case "soundcloud":
14703				g_objVideoPlayer.playSoundCloud(objItem.trackid);
14704			break;			
14705			case "wistia":
14706				g_objVideoPlayer.playWistia(objItem.videoid);
14707			break;			
14708		}
14709		
14710	}
14711	
14712	
14713	/**
14714	 * get the scale mode according the state (normal, fullscreen).
14715	 */
14716	this.getScaleMode = function(objSlide){
14717		
14718		if(!objSlide)
14719			var objSlide = t.getCurrentSlide();
14720		
14721		var slideType = t.getSlideType(objSlide);
14722				
14723		//return media scale mode
14724		if(slideType != "image")
14725			return(g_options.slider_scale_mode_media);
14726		
14727		if(g_options.slider_scale_mode == g_options.slider_scale_mode_fullscreen)
14728			return(g_options.slider_scale_mode);
14729		
14730		if(g_gallery.isFullScreen() == true)
14731			return(g_options.slider_scale_mode_fullscreen);
14732		else
14733			return(g_options.slider_scale_mode);
14734		
14735	}
14736	
14737	
14738	/**
14739	 * get slider objects
14740	 */
14741	this.getObjects = function(){
14742		
14743		var obj = {
14744				g_objSlider: g_objSlider,
14745				g_objInner: g_objInner,
14746				g_options: g_options,
14747				g_objZoomSlider: g_objZoomSlider
14748		};
14749				
14750		return(obj);
14751	}
14752	
14753	
14754	/**
14755	 * get zoom object
14756	 */
14757	this.getObjZoom = function(){
14758		
14759		return(g_objZoomSlider);
14760	}
14761	
14762	
14763	
14764	/**
14765	 * get slider options
14766	 */
14767	this.getOptions = function(){
14768		
14769		return(g_options);
14770	}
14771	
14772	
14773	/**
14774	 * get slider element
14775	 */
14776	this.getElement = function(){
14777		
14778		return(g_objSlider);
14779	}
14780	
14781	/**
14782	 * get video object
14783	 */
14784	this.getVideoObject = function(){
14785		return(g_objVideoPlayer);
14786	}
14787	
14788	
14789	/**
14790	 * return true if current slider image fit the slider
14791	 * @returns
14792	 */
14793	this.isCurrentSlideImageFit = function(){
14794		var objSlide = t.getCurrentSlide();
14795
14796		var slideType = t.getSlideType(objSlide);
14797		
14798		validateSlideType("image", objSlide);
14799		
14800		var objImage = t.getSlideImage(objSlide);
14801		
14802		//if image don't yet added to dom, return false
14803		if(objImage.length == 0)
14804			return(false);
14805		
14806		var isFit = g_functions.isImageFitParent(objImage);
14807		
14808		return(isFit);
14809	}
14810	
14811	
14812	/**
14813	 * check if current image in place
14814	 */
14815	this.isCurrentImageInPlace = function(){
14816		
14817		var objImage = t.getSlideImage();
14818		if(objImage.length == 0)
14819			return(false);
14820
14821		var scaleMode = t.getScaleMode();
14822		var objPadding = t.getObjImagePadding();
14823		var objItem = getSlideItem();
14824		
14825		var objParent = objImage.parent();
14826		
14827		var objFitSize = g_functions.getImageInsideParentData(objParent, objItem.imageWidth, objItem.imageHeight, scaleMode, objPadding);
14828		var objSize = g_functions.getElementSize(objImage);
14829
14830		var output = false;
14831		
14832		if(objFitSize.imageWidth == objSize.width)
14833			output = true;
14834				
14835		return(output);
14836	}
14837	
14838	
14839	/**
14840	 * if slide is bussy in some action
14841	 */
14842	this.isSlideActionActive = function(){
14843		
14844		return g_objVideoPlayer.isVisible();
14845	}
14846	
14847	/**
14848	 * return if swipe action active
14849	 */
14850	this.isSwiping = function(){
14851		if(!g_objTouchSlider)
14852			return(false);
14853		
14854		var isActive = g_objTouchSlider.isTouchActive();
14855		
14856		return(isActive);
14857	}
14858	
14859	
14860	/**
14861	 * if slider preloading image (if preloader visible)
14862	 */
14863	this.isPreloading = function(){
14864		
14865		var objPreloader = getSlidePreloader();
14866		if(objPreloader.is(":visible"))
14867			return(true);
14868		
14869		return(false);
14870	}
14871	
14872	/**
14873	 * set the options
14874	 */
14875	this.setOptions = function(objOptions){
14876
14877		//change options by prefix
14878		if(g_optionsPrefix)
14879			objOptions = g_functions.convertCustomPrefixOptions(objOptions, g_optionsPrefix, "slider");
14880		
14881		g_options = jQuery.extend(g_options, objOptions);
14882		
14883	}
14884	
14885	
14886	/**
14887	 * set the slider size
14888	 * works well on resize too.
14889	 */
14890	this.setSize = function(width, height){
14891		
14892		 if(width < 0 || height < 0)
14893			 return(true);
14894		
14895		 var objCssSlider = {};
14896		 objCssSlider["width"] = width + "px";
14897		 objCssSlider["height"] = height + "px";
14898		 g_objSlider.css(objCssSlider);
14899		 		 
14900		 //set inner:
14901		 var objCssInner = {};
14902		 objCssInner["height"] = height + "px";
14903		 objCssInner["top"] = "0px";
14904		 objCssInner["left"] = "0px";
14905		 g_objInner.css(objCssInner);
14906		 
14907		//set slide wrapper
14908		 var objCssSlide = {};
14909		 objCssSlide["height"] = height + "px";
14910		 objCssSlide["width"] = width + "px";
14911		 
14912		 g_objSlide1.css(objCssSlide);
14913		 g_objSlide2.css(objCssSlide);
14914		 g_objSlide3.css(objCssSlide);
14915		 
14916		 var itemWidth = width - g_options.slider_item_padding_left - g_options.slider_item_padding_right;
14917		 var itemHeight = height - g_options.slider_item_padding_top - g_options.slider_item_padding_bottom;
14918		 	
14919		 //set item wrapper
14920		 var objCssItemWrapper = {};
14921		 objCssItemWrapper["width"] = itemWidth + "px";
14922		 objCssItemWrapper["height"] = itemHeight + "px";
14923		 objCssItemWrapper["top"] = g_options.slider_item_padding_top + "px";
14924		 objCssItemWrapper["left"] = g_options.slider_item_padding_left + "px";
14925		 
14926		 g_objSlider.find(".ug-item-wrapper").css(objCssItemWrapper);		 
14927		 
14928		 
14929		 //set text panel size
14930		 if(g_objTextPanel){
14931			 g_objTextPanel.setSizeByParent();
14932		 }
14933		 
14934		 positionElements();
14935		 
14936		 //set image to slides
14937		 resizeSlideItem(g_objSlide1);
14938		 resizeSlideItem(g_objSlide2);
14939		 resizeSlideItem(g_objSlide3);
14940		 
14941		 positionSlides();
14942		 		 
14943		 //set video player size
14944		 var currentSlideType = t.getSlideType();
14945		
14946		 if(currentSlideType != "image" && g_options.slider_video_constantsize == true){
14947			 
14948			 setVideoPlayerConstantSize();
14949		 }else{	
14950			 var videoWidth = width - g_options.slider_video_padding_left - g_options.slider_video_padding_right;
14951			 var videoHeight = height - g_options.slider_video_padding_top - g_options.slider_video_padding_bottom;
14952			 
14953			 //set video player size
14954			 g_objVideoPlayer.setSize(videoWidth, videoHeight);
14955		 }
14956		 
14957		 setVideoPlayerPosition();
14958		 
14959	}
14960	
14961	
14962	/**
14963	 * refresh slide items after options change
14964	 */
14965	this.refreshSlideItems = function(){
14966		 
14967		if(t.isAnimating() == true)
14968			return(true);
14969		
14970		 resizeSlideItem(g_objSlide1);
14971		 resizeSlideItem(g_objSlide2);
14972		 resizeSlideItem(g_objSlide3);
14973		 positionSlides();
14974		 
14975	}
14976	
14977	
14978	/**
14979	 * is mouse over the slider
14980	 */
14981	this.isMouseOver = function(){
14982		
14983		return g_objSlider.ismouseover();
14984	}
14985	
14986	/**
14987	 * set slider position
14988	 */
14989	this.setPosition = function(left, top){
14990		
14991		g_functions.placeElement(g_objSlider, left, top);
14992			
14993	}
14994	
14995	
14996	/**
14997	 * zoom in
14998	 */
14999	this.zoomIn = function(){
15000		if(!g_objZoomSlider)
15001			return(true);
15002		
15003		g_objZoomSlider.zoomIn();
15004	}
15005	
15006	/**
15007	 * zoom out
15008	 */
15009	this.zoomOut = function(){
15010		
15011		if(!g_objZoomSlider)
15012			return(true);
15013		
15014		g_objZoomSlider.zoomOut();
15015			
15016	}
15017	
15018	/**
15019	 * zoom back to original
15020	 */
15021	this.zoomBack = function(){
15022		
15023		if(!g_objZoomSlider)
15024			return(true);
15025		
15026		g_objZoomSlider.zoomBack();	
15027	}
15028	
15029	
15030}
15031
15032/** -------------- TextPanel class ---------------------*/
15033
15034function UGTextPanel(){
15035	
15036	var t = this;
15037	var g_objPanel, g_objParent, g_objTitle, g_objDesc;
15038	var g_objBG, g_objTextWrapper, g_gallery;
15039	var g_functions = new UGFunctions(), g_optionsPrefix = "";
15040	
15041	var g_options = {
15042			textpanel_align:"bottom",					//(top , bottom), textpanel align according the parent
15043			textpanel_margin:0,							//margin from the textpanel position according the textpanel_align
15044			textpanel_text_valign:"middle",				//middle, top, bottom - text vertical align
15045			textpanel_padding_top:10,					//textpanel padding top 
15046			textpanel_padding_bottom:10,				//textpanel padding bottom
15047			textpanel_height: null,						//textpanel height. if null it will be set dynamically
15048			textpanel_padding_title_description: 5,		//the space between the title and the description
15049			textpanel_padding_right: 11,				//cut some space for text from right
15050			textpanel_padding_left: 11,					//cut some space for text from left
15051			textpanel_fade_duration: 200,				//the fade duration of textpanel appear
15052			textpanel_enable_title: true,				//enable the title text
15053			textpanel_enable_description: true,			//enable the description text
15054			textpanel_enable_bg: true,					//enable the textpanel background
15055			textpanel_bg_color:"#000000",				//textpanel background color
15056			textpanel_bg_opacity: 0.4,					//textpanel background opacity
15057			
15058			textpanel_title_color:null,					//textpanel title color. if null - take from css
15059			textpanel_title_font_family:null,			//textpanel title font family. if null - take from css
15060			textpanel_title_text_align:null,			//textpanel title text align. if null - take from css
15061			textpanel_title_font_size:null,				//textpanel title font size. if null - take from css
15062			textpanel_title_bold:null,					//textpanel title bold. if null - take from css
15063			textpanel_css_title:{},						//textpanel additional css of the title
15064
15065			textpanel_desc_color:null,					//textpanel description font family. if null - take from css
15066			textpanel_desc_font_family:null,			//textpanel description font family. if null - take from css
15067			textpanel_desc_text_align:null,				//textpanel description text align. if null - take from css
15068			textpanel_desc_font_size:null,				//textpanel description font size. if null - take from css
15069			textpanel_desc_bold:null,					//textpanel description bold. if null - take from css
15070			textpanel_css_description:{},				//textpanel additional css of the description
15071			
15072			textpanel_desc_style_as_title: false,		//set that the description style will be as title
15073			
15074			textpanel_bg_css:{}							//textpanel background css
15075	};
15076	
15077	var g_temp = {
15078			isFirstTime: true,
15079			setInternalHeight: true,	//flag if set internal height or not
15080			lastTitleBottom: 0,
15081			lastDescHeight: 0
15082	};
15083	
15084	
15085	/**
15086	 * position elements from top
15087	 */
15088	function positionElementsTop(animateHeight, startY){
15089		
15090		if(!startY)
15091			var startY = g_options.textpanel_padding_top;
15092		
15093		//place title
15094		var maxy = startY;
15095		
15096		//place title
15097		if(g_objTitle){
15098			var titleY = maxy;
15099			g_functions.placeElement(g_objTitle, 0, titleY);
15100			
15101			var isTitleVisible = g_objTitle.is(":visible");
15102			if(isTitleVisible == true){
15103				var objTitleSize = g_functions.getElementSize(g_objTitle);
15104				
15105				var maxy = objTitleSize.bottom;
15106				if(maxy > 0)
15107					g_temp.lastTitleBottom = maxy;
15108			}else{
15109				var maxy = 20;		//get last or assumed maxy
15110				
15111				if(g_temp.lastTitleBottom > 0)
15112					maxy = g_temp.lastTitleBottom;
15113			}
15114			
15115		}
15116		
15117				
15118		//place description
15119		var textDesc = "";
15120		if(g_objDesc)
15121			textDesc = jQuery.trim(g_objDesc.text());
15122		
15123		if(textDesc != ""){
15124			
15125			var descY = maxy;
15126						
15127			if(g_objTitle)
15128				descY += g_options.textpanel_padding_title_description;
15129			
15130			g_functions.placeElement(g_objDesc, 0, descY);
15131			
15132			var isVisible = jQuery(g_objDesc).is(":visible");
15133			
15134			if(isVisible == true){
15135				var objDescSize = g_functions.getElementSize(g_objDesc);
15136				maxy = objDescSize.bottom;
15137				
15138				if(objDescSize.height > 0)
15139					g_temp.lastDescHeight = objDescSize.height;
15140				
15141			}else{
15142				var descHeight = 16;			//take from last saved
15143				if(g_temp.lastDescHeight > 0)
15144					descHeight = g_temp.lastDescHeight;
15145				
15146				maxy = descY + descHeight;
15147			}
15148			
15149		}
15150		
15151		
15152		//change panel height
15153		if(!g_options.textpanel_height && g_temp.setInternalHeight == true){
15154			
15155			var panelHeight = maxy + g_options.textpanel_padding_bottom;		
15156			
15157			setHeight(panelHeight, animateHeight);
15158		}
15159		
15160	}
15161	
15162	/**
15163	 * get total text and description height
15164	 */
15165	function getTotalTextHeight(){
15166		var totalHeight = 0;
15167		
15168		if(g_objTitle)
15169			totalHeight += g_objTitle.outerHeight();
15170		
15171		if(g_objDesc){
15172			var textDesc = "";
15173			if(g_objDesc)
15174				textDesc = jQuery.trim(g_objDesc.text());
15175			
15176			if(textDesc != ""){
15177				if(g_objTitle)
15178					totalHeight += g_options.textpanel_padding_title_description;
15179				
15180				totalHeight += g_objDesc.outerHeight();
15181			}
15182		
15183		}
15184		
15185		
15186		return(totalHeight);
15187	}
15188	
15189	
15190	/**
15191	 * position elements to center
15192	 */
15193	function positionElementsMiddle(){
15194		
15195		var totalTextHeight = getTotalTextHeight();
15196		var startY = (g_objTextWrapper.height() - totalTextHeight) / 2;
15197		
15198		positionElementsTop(false, startY);
15199	}
15200	
15201	
15202	/**
15203	 * position elements to bottom
15204	 */
15205	function positionElementBottom(){
15206		
15207		var totalTextHeight = getTotalTextHeight();
15208		var startY = g_objTextWrapper.height() - totalTextHeight - g_options.textpanel_padding_bottom;
15209		
15210		positionElementsTop(false, startY);
15211	}
15212	
15213	
15214	/**
15215	 * position elements inside the panel
15216	 */
15217	this.positionElements = function(animateHeight){
15218
15219		//if(g_objPanel.is(":visible") == false)
15220			//trace("the text panel is hidden. can't position elements")
15221		
15222		//if height not set, position only top
15223		if(!g_options.textpanel_height || g_options.textpanel_text_valign == "top"){
15224			positionElementsTop(animateHeight);
15225			return(false);
15226		}
15227		
15228		switch(g_options.textpanel_text_valign){
15229			default:
15230			case "top":
15231				positionElementsTop(false);		//no animation in this case
15232			break;
15233			case "bottom":
15234				positionElementBottom();
15235			break;
15236			case "center":
15237			case "middle":
15238				positionElementsMiddle();
15239			break;
15240		}
15241		
15242	}
15243	
15244	
15245	/**
15246	 * set new panel height
15247	 */
15248	function setHeight(height, animateHeight){
15249		
15250		if(!animateHeight)
15251			var animateHeight = false;
15252		
15253		if(animateHeight == true){
15254			
15255			if(g_objBG){
15256				
15257				//avoid background jumps
15258				var currentHeight = g_objBG.height();
15259				if(height > currentHeight)
15260					g_objBG.height(height);				
15261			}
15262			
15263			var objCss = {height: height+"px"};
15264			g_objPanel.add(g_objTextWrapper).animate(objCss, g_options.textpanel_fade_duration);
15265			
15266		}else{
15267			
15268			if(g_objBG)
15269				g_objBG.height(height);		
15270			
15271			g_objPanel.add(g_objTextWrapper).height(height);
15272		}
15273		
15274	}
15275	
15276	
15277	
15278	
15279	/**
15280	 * init the panel
15281	 */
15282	this.init = function(objGallery, customOptions, optionsPrefix){
15283				
15284		g_gallery = objGallery;
15285		
15286		//change options by prefix
15287		if(optionsPrefix){
15288			g_optionsPrefix = optionsPrefix;
15289			customOptions = g_functions.convertCustomPrefixOptions(customOptions,g_optionsPrefix,"textpanel");			
15290			
15291		}
15292		
15293		if(customOptions)
15294			g_options = jQuery.extend(g_options, customOptions);
15295		
15296		//validation:
15297		if(g_options.textpanel_enable_title == false && g_options.textpanel_enable_description == false)
15298			throw new Error("Textpanel Error: The title or description must be enabled");
15299		
15300		if(g_options.textpanel_height && g_options.textpanel_height < 0)
15301			g_options.textpanel_height = null;
15302		
15303		//copy desc style from title
15304		if(g_options.textpanel_desc_style_as_title == true){
15305			if(!g_options.textpanel_desc_color)
15306				g_options.textpanel_desc_color = g_options.textpanel_title_color;
15307			
15308			if(!g_options.textpanel_desc_bold)
15309				g_options.textpanel_desc_bold = g_options.textpanel_title_bold;
15310			
15311			if(!g_options.textpanel_desc_font_family)
15312				g_options.textpanel_desc_font_family = g_options.textpanel_title_font_family;
15313			
15314			if(!g_options.textpanel_desc_font_size)
15315				g_options.textpanel_desc_font_size = g_options.textpanel_title_font_size;
15316			
15317			if(!g_options.textpanel_desc_text_align)
15318				g_options.textpanel_desc_text_align = g_options.textpanel_title_text_align;
15319		}
15320		
15321	}
15322	
15323	
15324	/**
15325	 * append the bullets html to some parent
15326	 */
15327	this.appendHTML = function(objParent, addClass){
15328		g_objParent = objParent;
15329		
15330		if(addClass){
15331			addClass = " "+addClass;
15332		}else
15333			addClass = "";
15334		
15335		var html = "<div class='ug-textpanel"+addClass+"'>";
15336		
15337		if(g_options.textpanel_enable_bg == true)
15338			html += "<div class='ug-textpanel-bg"+addClass+"'></div>";
15339		
15340		html += "<div class='ug-textpanel-textwrapper"+addClass+"'>";
15341		
15342		if(g_options.textpanel_enable_title == true)
15343			html += "<div class='ug-textpanel-title"+addClass+"'></div>";
15344		
15345		if(g_options.textpanel_enable_description == true)
15346			html += "<div class='ug-textpanel-description"+addClass+"'></div>";
15347		
15348		html += "</div></div>";
15349		
15350		objParent.append(html);
15351		
15352		g_objPanel = objParent.children(".ug-textpanel");
15353		g_objTextWrapper = g_objPanel.children(".ug-textpanel-textwrapper");
15354		
15355		setCss();
15356		
15357	}
15358	
15359	
15360	/**
15361	 * set panel css according the options
15362	 */
15363	function setCss(){
15364				
15365		//set background css		
15366		if(g_options.textpanel_enable_bg == true){
15367			g_objBG = g_objPanel.children(".ug-textpanel-bg");
15368			g_objBG.fadeTo(0,g_options.textpanel_bg_opacity);
15369			
15370			var objCssBG = {"background-color":g_options.textpanel_bg_color};
15371			objCssBG = jQuery.extend(objCssBG, g_options.textpanel_bg_css);
15372			
15373			g_objBG.css(objCssBG);
15374		}
15375		
15376		
15377		//set title css from options
15378		if(g_options.textpanel_enable_title == true){
15379			g_objTitle = g_objTextWrapper.children(".ug-textpanel-title");
15380			var objCssTitle = {};
15381			
15382			if(g_options.textpanel_title_color !== null)
15383				objCssTitle["color"] = g_options.textpanel_title_color;
15384			
15385			if(g_options.textpanel_title_font_family !== null)
15386				objCssTitle["font-family"] = g_options.textpanel_title_font_family;
15387			
15388			if(g_options.textpanel_title_text_align !== null)
15389				objCssTitle["text-align"] = g_options.textpanel_title_text_align;
15390			
15391			if(g_options.textpanel_title_font_size !== null)
15392				objCssTitle["font-size"] = g_options.textpanel_title_font_size+"px";
15393			
15394			if(g_options.textpanel_title_bold !== null){
15395				
15396				if(g_options.textpanel_title_bold === true)
15397					objCssTitle["font-weight"] = "bold";
15398				else
15399					objCssTitle["font-weight"] = "normal";
15400			
15401			}
15402			
15403			//set additional css
15404			if(g_options.textpanel_css_title)
15405				objCssTitle = jQuery.extend(objCssTitle, g_options.textpanel_css_title);
15406			
15407			g_objTitle.css(objCssTitle);
15408		}
15409		
15410		//set description css
15411		if(g_options.textpanel_enable_description == true){
15412			g_objDesc = g_objTextWrapper.children(".ug-textpanel-description");
15413			
15414			var objCssDesc = {};
15415			
15416			if(g_options.textpanel_desc_color !== null)
15417				objCssDesc["color"] = g_options.textpanel_desc_color;
15418			
15419			if(g_options.textpanel_desc_font_family !== null)
15420				objCssDesc["font-family"] = g_options.textpanel_desc_font_family;
15421			
15422			if(g_options.textpanel_desc_text_align !== null)
15423				objCssDesc["text-align"] = g_options.textpanel_desc_text_align;
15424			
15425			if(g_options.textpanel_desc_font_size !== null)
15426				objCssDesc["font-size"] = g_options.textpanel_desc_font_size+"px";
15427			
15428			if(g_options.textpanel_desc_bold !== null){
15429				
15430				if(g_options.textpanel_desc_bold === true)
15431					objCssDesc["font-weight"] = "bold";
15432				else
15433					objCssDesc["font-weight"] = "normal";
15434			
15435			}
15436			
15437			//set additional css
15438			if(g_options.textpanel_css_title)
15439				objCssDesc = jQuery.extend(objCssDesc, g_options.textpanel_css_description);
15440				
15441			g_objDesc.css(objCssDesc);
15442		}
15443		
15444	}
15445	
15446	/**
15447	 * on item change, set the text
15448	 */
15449	function onItemChange(){
15450		var objItem = g_gallery.getSelectedItem();
15451		t.setText(objItem.title, objItem.description);
15452	}
15453	
15454	
15455	/**
15456	 * init events
15457	 */
15458	function initEvents(){
15459		
15460		//on item change, set the text in the slider.
15461		jQuery(g_gallery).on(g_gallery.events.ITEM_CHANGE, onItemChange);
15462	}
15463	
15464	
15465	/**
15466	 * destroy the events
15467	 */
15468	this.destroy = function(){
15469		jQuery(g_gallery).off(g_gallery.events.ITEM_CHANGE);
15470	}
15471	
15472	/**
15473	 * run the text panel
15474	 */
15475	this.run = function(){
15476		
15477		t.setSizeByParent();
15478		
15479		initEvents();
15480	}
15481	
15482	/**
15483	 * set panel size
15484	 */
15485	this.setPanelSize = function(panelWidth, panelHeight){
15486		
15487		g_temp.setInternalHeight = true;
15488		
15489		if(!panelHeight)
15490			var panelHeight = 80;		//some default number
15491		else
15492			g_temp.setInternalHeight = false;
15493		
15494		if(g_options.textpanel_height)	
15495			panelHeight = g_options.textpanel_height;
15496		
15497		g_objPanel.width(panelWidth);
15498		g_objPanel.height(panelHeight);
15499		
15500		//set background size
15501		if(g_objBG){
15502			g_objBG.width(panelWidth);
15503			g_objBG.height(panelHeight);
15504		}
15505		
15506		//set textwrapper size and position
15507		var textWrapperWidth = panelWidth - g_options.textpanel_padding_left - g_options.textpanel_padding_right;
15508		var textWrapperLeft = g_options.textpanel_padding_left;
15509		
15510		g_functions.setElementSizeAndPosition(g_objTextWrapper, textWrapperLeft, 0, textWrapperWidth, panelHeight);
15511		
15512		//set text width
15513		if(g_objTitle)
15514			g_objTitle.width(textWrapperWidth);
15515		
15516		//set description height
15517		if(g_objDesc)
15518			g_objDesc.width(textWrapperWidth);
15519		
15520		if(g_temp.isFirstTime == false)
15521			t.positionElements(false);
15522	}
15523	
15524	
15525	/**
15526	 * set size by parent. the height is set to default meanwhile
15527	 */
15528	this.setSizeByParent = function(){
15529				
15530		var objSize = g_functions.getElementSize(g_objParent);
15531		t.setPanelSize(objSize.width);
15532	}
15533	
15534	/**
15535	 * set plain sext without other manipulations
15536	 */
15537	this.setTextPlain = function(title, description){
15538
15539		if(g_objTitle)
15540			g_objTitle.html(title);
15541		
15542		if(g_objDesc)
15543			g_objDesc.html(description);
15544		
15545	}
15546	
15547	
15548	/**
15549	 * set html text
15550	 */
15551	this.setText = function(title, description){
15552		
15553		if(g_temp.isFirstTime == true){
15554			
15555			t.setTextPlain(title, description);
15556			
15557			g_temp.isFirstTime = false;
15558			
15559			t.positionElements(false);
15560		
15561		}else{		//width animation
15562			
15563			g_objTextWrapper.stop().fadeTo(g_options.textpanel_fade_duration,0,function(){
15564				
15565				t.setTextPlain(title, description);
15566				
15567				t.positionElements(true);
15568				
15569				jQuery(this).fadeTo(g_options.textpanel_fade_duration,1);
15570			});
15571			
15572		}
15573		
15574	}
15575	
15576	
15577		
15578	
15579	/**
15580	 * position the panel
15581	 */
15582	this.positionPanel = function(customTop, customLeft){
15583		
15584		var objCss = {};
15585		
15586		if(customTop !== undefined && customTop !== null){
15587			objCss.top = customTop;
15588			objCss.bottom = "auto";
15589		}else{
15590			
15591			switch(g_options.textpanel_align){
15592				case "top":
15593					objCss.top = g_options.textpanel_margin + "px";
15594				break;
15595				case "bottom":
15596					objCss.top = "auto";
15597					objCss.bottom = g_options.textpanel_margin + "px";
15598				break;
15599				case "middle":
15600					objCss.top = g_functions.getElementRelativePos(g_objPanel, "middle", g_options.textpanel_margin);
15601				break;
15602			}
15603			
15604		}
15605		
15606		if(customLeft !== undefined && customLeft !== null)
15607			objCss.left = customLeft;
15608		
15609		g_objPanel.css(objCss);
15610	}
15611	
15612	
15613	/**
15614	 * set custom options
15615	 */
15616	this.setOptions = function(objOptions){
15617		
15618		if(g_optionsPrefix)
15619			objOptions = g_functions.convertCustomPrefixOptions(objOptions, g_optionsPrefix, "textpanel");
15620		
15621		g_options = jQuery.extend(g_options, objOptions);
15622				
15623	}
15624	
15625	
15626	/**
15627	 * get html element
15628	 */
15629	this.getElement = function(){
15630		
15631		return(g_objPanel);
15632	}
15633	
15634	/**
15635	 * get element size
15636	 */
15637	this.getSize = function(){
15638		
15639		var objSize = g_functions.getElementSize(g_objPanel);
15640		return(objSize);
15641	}
15642	
15643	
15644	/**
15645	 * refresh panel size, position and contents
15646	 */
15647	this.refresh = function(toShow, noPosition, panelWidth, panelHeight){
15648		
15649		setCss();
15650		
15651		if(!panelWidth)
15652			t.setSizeByParent();
15653		else
15654			t.setPanelSize(panelWidth, panelHeight);
15655		
15656		t.positionElements(false);
15657		
15658		if(noPosition !== true)
15659			t.positionPanel();
15660		
15661		if(toShow === true)
15662			t.show();		
15663	}
15664	
15665	
15666	/**
15667	 * hide the panel
15668	 */
15669	this.hide = function(){
15670		
15671		g_objPanel.hide();
15672	}
15673	
15674	/**
15675	 * show the panel
15676	 */
15677	this.show = function(){
15678		g_objPanel.show();
15679	}
15680	
15681	/**
15682	 * get options
15683	 */
15684	this.getOptions = function(){
15685		return(g_options);
15686	}
15687	
15688	/**
15689	 * get text panel option
15690	 */
15691	this.getOption = function(optionName){
15692		
15693		if(g_options.hasOwnProperty(optionName) == false)
15694			return(null);
15695		
15696		return(g_options[optionName]);
15697	}
15698	
15699	
15700}
15701
15702/** -------------- UGZoomButtonsPanel class ---------------------*/
15703
15704/**
15705 * zoom buttons panel class
15706 */
15707function UGZoomButtonsPanel(){
15708	
15709	var t = this;
15710	var g_objPanel, g_objParent, g_objButtonPlus, g_objButtonMinus, g_objButtonReturn;
15711	var g_slider = new UGSlider;
15712	var g_functions = new UGFunctions();
15713	
15714	var g_options = {
15715		slider_zoompanel_skin: ""		//skin of the zoom panel, if empty inherit from gallery skin
15716	};
15717	
15718	var g_temp = {
15719		
15720	};
15721	
15722	
15723	/**
15724	 * init the panel
15725	 */
15726	this.init = function(objSlider, customOptions){
15727		
15728		g_slider = objSlider;
15729		
15730		if(customOptions)
15731			g_options = jQuery.extend(g_options, customOptions);		
15732	}
15733	
15734	
15735	/**
15736	 * append the bullets html to some parent
15737	 */
15738	this.appendHTML = function(objParent){
15739		g_objParent = objParent;
15740		
15741		var html = "<div class='ug-slider-control ug-zoompanel ug-skin-"+g_options.slider_zoompanel_skin+"'>";
15742		
15743			html += "<div class='ug-zoompanel-button ug-zoompanel-plus'></div>";
15744			html += "<div class='ug-zoompanel-button ug-zoompanel-minus ug-zoompanel-button-disabled'></div>";
15745			html += "<div class='ug-zoompanel-button ug-zoompanel-return ug-zoompanel-button-disabled'></div>";
15746		
15747		html += "</div>";
15748		
15749		objParent.append(html);
15750		
15751		g_objPanel = objParent.children(".ug-zoompanel");
15752		g_objButtonPlus = g_objPanel.children(".ug-zoompanel-plus");
15753		g_objButtonMinus = g_objPanel.children(".ug-zoompanel-minus");
15754		g_objButtonReturn = g_objPanel.children(".ug-zoompanel-return");
15755		
15756	}
15757	
15758	
15759	/**
15760	 * set objects - use it instead insert html
15761	 */
15762	this.setObjects = function(objButtonPlus, objButtonMinus, objButtonReturn){
15763		
15764		g_objButtonPlus = objButtonPlus;
15765		g_objButtonMinus = objButtonMinus;
15766		g_objButtonReturn = objButtonReturn;
15767		
15768		if(g_objButtonMinus)
15769			g_objButtonMinus.addClass("ug-zoompanel-button-disabled");
15770		
15771		if(g_objButtonReturn)
15772			g_objButtonReturn.addClass("ug-zoompanel-button-disabled");
15773			
15774	}
15775	
15776	
15777	/**
15778	 * get buttons element
15779	*/
15780	this.getElement = function(){
15781		
15782		return(g_objPanel);
15783	}
15784	
15785	
15786	/**
15787	 * check if the button disabled
15788	 */
15789	function isButtonDisabled(objButton){
15790		
15791		if(!objButton)
15792			return(true);
15793		
15794		if(objButton.hasClass("ug-zoompanel-button-disabled"))
15795			return(true);
15796		
15797		return(false);
15798	}
15799	
15800	
15801	/**
15802	 * disable some button
15803	 */
15804	function disableButton(objButton){
15805		
15806		if(objButton)
15807			objButton.addClass("ug-zoompanel-button-disabled");
15808	}
15809	
15810	/**
15811	 * enable some button
15812	 */
15813	function enableButton(objButton){
15814		
15815		if(objButton)
15816			objButton.removeClass("ug-zoompanel-button-disabled");		
15817	}
15818	
15819	
15820	/**
15821	 * on zoom change
15822	 */
15823	function onZoomChange(){
15824		
15825		//skip not image types
15826		if(g_slider.isCurrentSlideType("image") == false)
15827			return(true);
15828		
15829		var isFit = g_slider.isCurrentSlideImageFit();
15830		
15831		if(isFit == true){		//if fit, disable buttons
15832			
15833			if(isButtonDisabled(g_objButtonMinus) == false){			
15834				disableButton(g_objButtonMinus);
15835				disableButton(g_objButtonReturn);
15836			}
15837			
15838		}else{	//if not fit, enable minus buttons
15839			
15840			if(isButtonDisabled(g_objButtonMinus) == true){
15841				enableButton(g_objButtonMinus);
15842				enableButton(g_objButtonReturn);				
15843			}
15844			
15845		}
15846			
15847	}
15848	
15849	/**
15850	 * init zoompanel events
15851	 */
15852	t.initEvents = function(){
15853		
15854		//add hover class on buttons
15855		g_functions.addClassOnHover(g_objButtonPlus, "ug-button-hover");
15856		g_functions.addClassOnHover(g_objButtonMinus, "ug-button-hover");
15857		g_functions.addClassOnHover(g_objButtonReturn, "ug-button-hover");
15858		
15859		//set buttons click events
15860		
15861		g_functions.setButtonOnClick(g_objButtonPlus, function(){
15862			
15863			if(isButtonDisabled(g_objButtonPlus) == true)
15864				return(true);
15865			
15866			g_slider.zoomIn();
15867		});
15868		
15869		g_functions.setButtonOnClick(g_objButtonMinus, function(){
15870			
15871			if(isButtonDisabled(g_objButtonMinus) == true)
15872				return(true);
15873			
15874			g_slider.zoomOut();
15875		});
15876		
15877		g_functions.setButtonOnClick(g_objButtonReturn, function(){
15878			
15879			if(isButtonDisabled(g_objButtonReturn) == true)
15880				return(true);
15881			
15882			g_slider.zoomBack();
15883		});
15884				
15885		//on zoom change event
15886		jQuery(g_slider).on(g_slider.events.ZOOM_CHANGE,onZoomChange);
15887		jQuery(g_slider).on(g_slider.events.ITEM_CHANGED,onZoomChange);
15888	
15889	}
15890	
15891	
15892}
15893
15894
15895/** -------------- UgBullets class ---------------------*/
15896
15897function UGBullets(){
15898	
15899	var t = this, g_numBullets = 0, g_gallery = new UniteGalleryMain();
15900	var g_objBullets, g_objParent, g_activeIndex = -1, g_bulletWidth;
15901	var g_functions = new UGFunctions();
15902	
15903	var g_temp = {
15904		isInited:false
15905	};
15906	
15907	var g_options = {
15908		bullets_skin: "",					//bullets_skin: ""		//skin of the bullets, if empty inherit from gallery skin
15909		bullets_addclass: "",					//bullets object class addition
15910		bullets_space_between:-1			//set the space between bullets. If -1 then will be set default space from the skins
15911	}
15912	
15913	
15914	/**
15915	 * the events
15916	 */
15917	this.events = {
15918		BULLET_CLICK : "bullet_click"
15919	};
15920	
15921	/**
15922	 * init the bullets
15923	 */
15924	this.init = function(gallery, customOptions, numBullets){
15925		g_gallery = gallery;
15926		
15927		if(numBullets)
15928			g_numBullets = numBullets;
15929		else	
15930			g_numBullets = g_gallery.getNumItems();
15931		
15932		g_temp.isInited = true;
15933		g_options = jQuery.extend(g_options, customOptions);
15934		
15935		if(g_options.bullets_skin == "")
15936			g_options.bullets_skin = g_options.gallery_skin;
15937		
15938	}
15939	
15940	/**
15941	 * add bullets to the html
15942	 */
15943	function setHtmlBullets(){
15944		var html = "";
15945		
15946		var addHtml = "";
15947		if(g_options.bullets_space_between != -1)
15948			addHtml = " style='margin-left:" + g_options.bullets_space_between + "px'";
15949		
15950		for(var i=0; i< g_numBullets; i++){
15951			if(i == 0)
15952				html += "<div class='ug-bullet'></div>";
15953			else
15954				html += "<div class='ug-bullet'"+addHtml+"></div>";
15955		}
15956		
15957		g_objBullets.html(html);
15958		
15959		//set bullet width value
15960		if(!g_bulletWidth){
15961			var objBullet = g_objBullets.find(".ug-bullet:first-child");
15962			if(objBullet.length)
15963				g_bulletWidth = objBullet.width();
15964		}
15965	}
15966
15967	/**
15968	 * get total bullets width
15969	 */
15970	this.getBulletsWidth = function(){
15971		if(g_numBullets == 0)
15972			return(0);
15973		
15974		if(!g_bulletWidth)
15975			return(0);
15976		
15977		var totalWidth = g_numBullets*g_bulletWidth+(g_numBullets-1)*g_options.bullets_space_between;
15978		return(totalWidth);
15979	}
15980	
15981	
15982	/**
15983	 * append the bullets html to some parent
15984	 */
15985	this.appendHTML = function(objParent){
15986		g_objParent = objParent;
15987		
15988		validateInited();
15989		var addClass = "";
15990		if(g_options.bullets_addclass != "")
15991			addClass = " " + g_options.bullets_addclass;
15992			
15993		var html = "<div class='ug-slider-control ug-bullets ug-skin-"+g_options.bullets_skin + addClass+"'>";
15994		
15995		html += "</div>";
15996		
15997		g_objBullets = jQuery(html);
15998		
15999		objParent.append(g_objBullets);
16000		
16001		setHtmlBullets();
16002		
16003		initEvents();
16004	}	
16005	
16006	
16007	/**
16008	 * update number of bullets
16009	 */
16010	this.updateNumBullets = function(numBullets){
16011		
16012		g_numBullets = numBullets;
16013		setHtmlBullets();
16014		initEvents();
16015	}
16016	
16017	
16018	/**
16019	 * 
16020	 * on bullet click
16021	 */
16022	function onBulletClick(objBullet){
16023				
16024		//filter not active only
16025		if(t.isActive(objBullet) == true)
16026			return(true);
16027		
16028		var index = objBullet.index();
16029			
16030		jQuery(t).trigger(t.events.BULLET_CLICK, index);
16031	}
16032	
16033	
16034	/**
16035	 * init the bullets events
16036	 * trigger bullet click event
16037	 */
16038	function initEvents(){
16039		
16040		var objBullets = g_objBullets.children(".ug-bullet");
16041		
16042		g_functions.setButtonOnClick(objBullets, onBulletClick);
16043		
16044		objBullets.on("mousedown mouseup",function(event){
16045			//event.preventDefault();
16046			return(false);
16047		});
16048		
16049	}
16050	
16051	
16052	/**
16053	 * get the bullets element
16054	 */
16055	this.getElement = function(){
16056		return g_objBullets;
16057	}
16058	
16059	
16060	/**
16061	 * set some item active
16062	 */
16063	this.setActive = function(index){
16064		validateInited();
16065		validateIndex(index);
16066		
16067		var children = g_objBullets.children(".ug-bullet");
16068		children.removeClass("ug-bullet-active");
16069		
16070		var bullet = jQuery(children[index]);
16071		bullet.addClass("ug-bullet-active");
16072		
16073		g_activeIndex = index;
16074	}
16075
16076	
16077	/**
16078	 * check if the bullet is active
16079	 */
16080	this.isActive = function(index){
16081		validateIndex(index);
16082		
16083		if(typeof index != "number")
16084			var objBullet = index;
16085		else{
16086			var objBullet = g_objBullets.children(".ug-bullet")[index];			
16087		}
16088		
16089		if(objBullet.hasClass("ug-bullet-active"))
16090				return(true);
16091		
16092		return(false);
16093	}
16094	
16095	
16096	/**
16097	 * get bullets number
16098	 */
16099	this.getNumBullets = function(){
16100		return(g_numBullets);
16101	}
16102	
16103	/**
16104	 * validate bullets index
16105	 */
16106	function validateIndex(index){
16107		if(index < 0 || index >= g_numBullets)
16108			throw new Error("wrong bullet index: " + index);
16109	}
16110	
16111	
16112	/**
16113	 * validate that the bullets are inited
16114	 */
16115	function validateInited(){
16116		
16117		if(g_temp.isInited == true)
16118			return(true);
16119		
16120		throw new Error("The bullets are not inited!");
16121	}
16122	
16123	
16124	
16125}
16126
16127/** -------------- UgProgressBar class ---------------------*/
16128
16129function UGProgressBar(){
16130	
16131	var t = this, g_isInited = false;
16132	var g_percent = 0, g_objBar, g_objInner, g_functions = new UGFunctions();
16133	
16134	var g_options = {
16135		slider_progressbar_color:"#ffffff",			//progress bar color
16136		slider_progressbar_opacity: 0.6,			//progress bar opacity
16137		slider_progressbar_line_width: 5			//progress bar line width
16138	}
16139	
16140	
16141	/**
16142	 * put progress pie to some wrapper
16143	 */
16144	this.put = function(g_objWrapper, userOptions){
16145		
16146		if(userOptions)
16147			g_options = jQuery.extend(g_options, userOptions);
16148		
16149		g_objWrapper.append("<div class='ug-progress-bar'><div class='ug-progress-bar-inner'></div></div>");
16150		g_objBar = g_objWrapper.children(".ug-progress-bar");
16151		g_objInner = g_objBar.children(".ug-progress-bar-inner");
16152		
16153		//init the objects
16154		g_objInner.css("background-color", g_options.slider_progressbar_color);
16155		g_objBar.height(g_options.slider_progressbar_line_width);
16156		g_objInner.height(g_options.slider_progressbar_line_width);
16157		g_objInner.width("0%");
16158		
16159		//set opacity old way (because ie bug)
16160		var opacity = g_options.slider_progressbar_opacity;
16161		
16162		var objInnerHTML = g_objInner[0];
16163		objInnerHTML.style.opacity = opacity;
16164		objInnerHTML.style.filter = 'alpha(opacity=' + opacity*100 + ')';
16165	}
16166	
16167	
16168	/**
16169	 * put the pie hidden
16170	 */
16171	this.putHidden = function(g_objWrapper, userOptions){
16172		t.put(g_objWrapper, userOptions);
16173		g_objBar.hide();
16174	}
16175	
16176	/**
16177	 * get the bar object
16178	 */
16179	this.getElement = function(){
16180		
16181		return(g_objBar);
16182	}
16183	
16184	/**
16185	 * set progress bar size
16186	 */
16187	this.setSize = function(width){
16188		
16189		g_objBar.width(width);
16190		g_objInner.width(width);
16191		t.draw();
16192	}
16193	
16194	
16195	/**
16196	 * set position
16197	 */
16198	this.setPosition = function(left, top, offsetLeft, offsetTop){
16199		
16200		g_functions.placeElement(g_objBar, left, top, offsetLeft, offsetTop);
16201	}
16202	
16203	
16204	/**
16205	 * draw the progress bar
16206	 */
16207	this.draw = function(){
16208		var innerWidth = g_percent * 100;
16209		
16210		g_objInner.width(innerWidth + "%");
16211	}
16212	
16213	
16214	/**
16215	 * set and draw the progress
16216	 */
16217	this.setProgress = function(percent){
16218		
16219		g_percent = g_functions.normalizePercent(percent);
16220		
16221		//debugLine(g_percent, true);
16222		
16223		t.draw();
16224	}
16225	
16226	/**
16227	 * get type string
16228	 */
16229	this.getType = function(){
16230		return("bar");
16231	}
16232	
16233}
16234
16235/** -------------- UgProgressPie class ---------------------*/
16236
16237function UGProgressPie(){
16238	
16239	var t = this, g_isInited = false;
16240	var g_percent, g_objPie, g_functions = new UGFunctions();
16241	
16242	var g_options = {
16243		slider_progresspie_type_fill: false,		//false is stroke, true is fill - the progress pie type, stroke of fill
16244		slider_progresspie_color1: "#B5B5B5", 		//the first color of the progress pie
16245		slider_progresspie_color2: "#E5E5E5",		//progress pie second color 
16246		slider_progresspie_stroke_width: 6,			//progress pie stroke width 
16247		slider_progresspie_width: 30,				//progess pie width
16248		slider_progresspie_height:30				//progress pie height
16249	}
16250	
16251	
16252	/**
16253	 * put progress pie to some wrapper
16254	 */
16255	this.put = function(g_objWrapper, userOptions){
16256		
16257		if(userOptions)
16258			g_options = jQuery.extend(g_options, userOptions);
16259			
16260		g_objWrapper.append("<canvas class='ug-canvas-pie' width='"+g_options.slider_progresspie_width+"' height='"+g_options.slider_progresspie_height+"'></canvas>");
16261		g_objPie = g_objWrapper.children(".ug-canvas-pie");
16262	}
16263	
16264	
16265	/**
16266	 * put the pie hidden
16267	 */
16268	this.putHidden = function(g_objWrapper, userOptions){
16269		t.put(g_objWrapper, userOptions);
16270		draw(0.1);
16271		g_objPie.hide();
16272	}
16273	
16274	
16275	/**
16276	 * get jquery object
16277	 */
16278	this.getElement = function(){
16279		return(g_objPie);
16280	}
16281	
16282	/**
16283	 * set position
16284	 */
16285	this.setPosition = function(left, top){
16286		
16287		g_functions.placeElement(g_objPie, left, top);
16288		
16289	}
16290	
16291	/**
16292	 * get the height and width of the object
16293	 */
16294	this.getSize = function(){
16295		
16296		var obj = {
16297			width: g_options.slider_progresspie_width,
16298			height: g_options.slider_progresspie_height
16299		};
16300		
16301		return(obj);
16302	}	
16303	
16304	/**
16305	 * draw the progress pie
16306	 */
16307	function draw(percent){
16308		
16309		if(!percent)
16310			var percent = 0;
16311		
16312		var radius = Math.min(g_options.slider_progresspie_width, g_options.slider_progresspie_height) / 2;
16313		
16314		var ctx = g_objPie[0].getContext('2d');
16315		
16316		//init the context
16317		if(g_isInited == false){
16318			
16319			g_isInited = true;
16320			
16321			ctx.rotate(Math.PI*(3/2));
16322			ctx.translate(-2 * radius,0);
16323		}		
16324		
16325		ctx.clearRect(0,0,g_options.slider_progresspie_width, g_options.slider_progresspie_height);
16326		
16327		var centerX = g_options.slider_progresspie_width / 2;
16328		var centerY = g_options.slider_progresspie_height / 2;
16329	    
16330		//draw main arc
16331		var startPoint = 0;
16332		var endPoint = percent * Math.PI * 2;
16333				
16334	    
16335		if(g_options.slider_progresspie_type_fill == true){		//fill
16336			
16337			ctx.beginPath();
16338				ctx.moveTo(centerX, centerY); 
16339			    ctx.arc(centerX,centerY,radius,startPoint, endPoint);
16340			    ctx.lineTo(centerX, centerY); 
16341			    
16342			    ctx.fillStyle = g_options.slider_progresspie_color1;
16343			    ctx.fill();
16344		    ctx.closePath();
16345		    
16346		}else{		//stroke
16347		    ctx.globalCompositeOperation = "source-over";
16348			
16349			ctx.beginPath();
16350				ctx.moveTo(centerX, centerY); 
16351			    ctx.arc(centerX,centerY,radius,startPoint, endPoint);
16352			    ctx.lineTo(centerX, centerY); 
16353			    
16354			    ctx.fillStyle = g_options.slider_progresspie_color1;
16355			    ctx.fill();
16356			ctx.closePath();
16357		    
16358		    ctx.globalCompositeOperation = "destination-out";
16359			
16360			var radius2 = radius - g_options.slider_progresspie_stroke_width;
16361		    
16362			ctx.beginPath();
16363								
16364				ctx.moveTo(centerX, centerY); 
16365			    ctx.arc(centerX,centerY,radius2,startPoint, endPoint);
16366			    ctx.lineTo(centerX, centerY); 
16367			    
16368			    ctx.fillStyle = g_options.slider_progresspie_color1;
16369			    ctx.fill();
16370			    
16371			ctx.closePath();
16372		}
16373	    
16374	    
16375		//draw rest arc (only on fill type):
16376	    if(g_options.slider_progresspie_type_fill == true){
16377			startPoint = endPoint;
16378			endPoint = Math.PI * 2;
16379			ctx.beginPath();
16380			    ctx.arc(centerX,centerY,radius,startPoint, endPoint);
16381			    ctx.lineTo(centerX, centerY); 
16382		    ctx.fillStyle = g_options.slider_progresspie_color2;
16383		    ctx.fill();
16384		    ctx.closePath();	    	
16385	    }
16386	    
16387	}
16388	
16389	
16390	/**
16391	 * set progress (0-1)
16392	 */
16393	this.setProgress = function(percent){
16394		
16395		percent = g_functions.normalizePercent(percent);
16396		
16397		g_percent = percent;
16398		draw(percent);
16399	}
16400	
16401	/**
16402	 * get type string
16403	 */
16404	this.getType = function(){
16405		return("pie");
16406	}
16407	
16408}
16409
16410/**f
16411 * touch thumbs control class
16412 * addon to strip gallery
16413 */
16414function UGTouchSliderControl(){
16415	
16416	var g_objSlider, g_objInner, g_parent = new UGSlider();
16417	var g_objParent, g_options, t=this;
16418	
16419	var g_functions = new UGFunctions();
16420	
16421	
16422	var g_options = {
16423		  slider_transition_continuedrag_speed: 250,				//the duration of continue dragging after drag end
16424		  slider_transition_continuedrag_easing: "linear",		//easing function of continue dragging animation
16425		  slider_transition_return_speed: 300,					//the duration of the "return to place" animation
16426		  slider_transition_return_easing: "easeInOutQuad"		//easing function of the "return to place" animation
16427	};
16428	
16429	var g_temp = {
16430		touch_active: false,		
16431		startMouseX: 0,		
16432		startMouseY: 0,
16433		lastMouseX: 0,
16434		lastMouseY: 0,
16435		startPosx:0, 
16436		startTime:0,
16437		isInitDataValid:false,
16438		slides: null,
16439		lastNumTouches:0,
16440		isDragging: false,
16441		storedEventID: "touchSlider",
16442		videoStartX: 0,
16443		isDragVideo: false,
16444		videoObject: null
16445	};
16446	
16447	
16448	/**
16449	 * get diff inner object position from current item pos
16450	 */
16451	function getDiffPosFromCurrentItem(slides){
16452		
16453		if(!slides)
16454			var slides = g_parent.getSlidesReference();
16455		
16456		var posCurrent = g_functions.getElementSize(slides.objCurrentSlide);
16457		var inPlaceX = -posCurrent.left;
16458		var objInnerSize = g_functions.getElementSize(g_objInner);
16459		var diffPos = inPlaceX - objInnerSize.left;
16460		
16461		return(diffPos);
16462	}
16463	
16464	/**
16465	 * check if the movement that was held is valid for slide change
16466	 */
16467	function isMovementValidForChange(){
16468		
16469		var slides = g_parent.getSlidesReference();
16470
16471		//check position, if more then half, move
16472		var diffPos = getDiffPosFromCurrentItem(slides);
16473		
16474		var breakSize = Math.round(slides.objCurrentSlide.width() * 3 / 8);
16475				
16476		if(Math.abs(diffPos) >= breakSize)
16477			return(true);
16478				
16479		//check gesture, if vertical mostly then not move
16480		var diffX = Math.abs(g_temp.lastMouseX - g_temp.startMouseX);
16481		var diffY = Math.abs(g_temp.lastMouseY - g_temp.startMouseY);
16482		
16483		//debugLine("diffx: " + diffX, true, true);
16484		
16485		if(diffX < 20)
16486			return(false);
16487		
16488		//if(diffY >= diffX)
16489			//return(false);
16490				
16491		//check time. Short time always move
16492		var endTime = jQuery.now();
16493		var diffTime = endTime - g_temp.startTime;
16494		
16495		//debugLine("time: " + diffTime, true);
16496		
16497		if(diffTime < 500)
16498			return(true);
16499		
16500					
16501		return(false);
16502	}
16503
16504	/**
16505	 * check tab event occured
16506	 * invokes on touchend event on the slider object
16507	 */
16508	this.isTapEventOccured = function(event){
16509		
16510		//validate one touch
16511		var arrTouches = g_functions.getArrTouches(event);
16512		var numTouches = arrTouches.length;
16513			
16514		if(numTouches != 0 || g_temp.lastNumTouches != 0){
16515			g_temp.lastNumTouches = numTouches;
16516			return(false);
16517		}
16518			
16519		g_temp.lastNumTouches = numTouches;
16520				
16521		var slides = g_parent.getSlidesReference();
16522
16523		//check position, if more then half, move
16524		var diffPos = getDiffPosFromCurrentItem(slides);
16525		
16526		//check gesture, if vertical mostly then not move
16527		var diffX = Math.abs(g_temp.lastMouseX - g_temp.startMouseX);
16528		var diffY = Math.abs(g_temp.lastMouseY - g_temp.startMouseY);
16529		
16530		//check by time
16531		var endTime = jQuery.now();
16532		var diffTime = endTime - g_temp.startTime;
16533		
16534		//combine move and time
16535		if(diffX < 20 && diffY < 50 && diffTime < 500)
16536			return(true);
16537		
16538		return(false);
16539	}
16540	
16541	/**
16542	 * return the item to place
16543	 */
16544	function returnToPlace(slides){
16545		
16546		if(g_parent.isInnerInPlace() == true)
16547			return(false);
16548						
16549		//trigger before return event
16550		g_objParent.trigger(g_parent.events.BEFORE_RETURN);
16551		
16552		if(!slides)
16553			var slides = g_parent.getSlidesReference();
16554		
16555		var posCurrent = g_functions.getElementSize(slides.objCurrentSlide);
16556		var destX = -posCurrent.left;
16557				
16558		//animate objects		
16559		g_objInner.animate({left:destX+"px"},{
16560			duration: g_options.slider_transition_return_speed,
16561			easing: g_options.slider_transition_continuedrag_easing,
16562			queue: false,
16563			progress: function(animation, number, remainingMS){
16564								
16565				//check drag video
16566				if(g_temp.isDragVideo == true){
16567					var objSize = g_functions.getElementSize(g_objInner);
16568					var innerX = objSize.left;
16569					
16570					var posDiff = innerX - destX;
16571					
16572					var videoPosX = g_temp.videoStartX + posDiff;
16573					g_temp.videoObject.css("left", videoPosX);
16574				}
16575				
16576			},
16577			complete: function(){
16578				g_objParent.trigger(g_parent.events.AFTER_RETURN);
16579			}
16580		});
16581		
16582	}
16583	
16584	
16585	/**
16586	 * 
16587	 * change the item to given direction
16588	 */
16589	function changeItem(direction){
16590		
16591		g_parent.getVideoObject().hide();
16592		g_parent.switchSlideNums(direction);
16593		g_parent.placeNabourItems();
16594
16595	}
16596	
16597	/**
16598	 * continue the dragging by changing the slides to the right place.
16599	 */
16600	function continueSlideDragChange(){
16601		
16602		//get data
16603		var slides = g_parent.getSlidesReference();
16604		
16605		var diffPos = getDiffPosFromCurrentItem(slides);
16606		
16607		if(diffPos == 0)
16608			return(false);
16609		
16610		var direction = (diffPos > 0) ? "left" : "right";
16611			
16612		var isReturn = false;
16613			
16614		switch(direction){
16615			case "right":	//change to prev item
16616				
16617				if( g_parent.isSlideHasItem(slides.objPrevSlide) ){
16618					
16619					var posPrev = g_functions.getElementSize(slides.objPrevSlide);
16620					var destX = -posPrev.left;
16621					
16622				}else	//return current item
16623					isReturn = true;
16624				
16625			break;	
16626			case "left":		//change to next item
16627				
16628				if( g_parent.isSlideHasItem(slides.objNextSlide) ){
16629					
16630					var posNext = g_functions.getElementSize(slides.objNextSlide);
16631					var destX = -posNext.left;
16632					
16633				}else					
16634					isReturn = true;				
16635			break;
16636	   }
16637		
16638		
16639		if(isReturn == true){
16640			returnToPlace(slides);
16641			
16642		}else{
16643						
16644			//animate objects
16645			g_objInner.stop().animate({left:destX+"px"},{
16646				duration: g_options.slider_transition_continuedrag_speed,
16647				easing: g_options.slider_transition_continuedrag_easing,
16648				queue: false,
16649				progress: function(){
16650					
16651					//check drag video
16652					if(g_temp.isDragVideo == true){
16653						var objSize = g_functions.getElementSize(g_objInner);
16654						var innerX = objSize.left;
16655						var posDiff = innerX - g_temp.startPosx;
16656						var videoPosX = g_temp.videoStartX + posDiff;
16657						g_temp.videoObject.css("left", videoPosX);
16658					}
16659					
16660				},
16661				always:function(){
16662					changeItem(direction);
16663					g_objParent.trigger(g_parent.events.AFTER_DRAG_CHANGE);
16664				}
16665			});
16666			
16667		}
16668				
16669		
16670	}
16671
16672	
16673	/**
16674	 * handle slider drag on mouse drag
16675	 */
16676	function handleSliderDrag(event){
16677		
16678		var diff = g_temp.lastMouseX - g_temp.startMouseX;
16679		
16680		if(diff == 0)
16681			return(true);
16682		
16683		var direction = (diff < 0) ? "left":"right";
16684		
16685		var objZoomSlider = g_parent.getObjZoom();
16686		
16687		//don't drag if the zoom panning enabled
16688		//store init position after image zoom pan end
16689		if(objZoomSlider){
16690			
16691			var isPanEnabled = objZoomSlider.isPanEnabled(event,direction);
16692						
16693			if(isPanEnabled == true){
16694				g_temp.isInitDataValid = false;
16695				return(true);				
16696			}else{
16697				
16698				if(g_temp.isInitDataValid == false){
16699					storeInitTouchData(event);
16700					return(true);
16701				}
16702				
16703			}
16704		}
16705		
16706		//set inner div position
16707		var currentPosx = g_temp.startPosx + diff;
16708		
16709		//check out of borders and slow down the motion:
16710		if(diff > 0 && currentPosx > 0)
16711			currentPosx = currentPosx / 3;		
16712		
16713		else if(diff < 0 ){
16714			
16715			var innerEnd = currentPosx + g_objInner.width();
16716			var sliderWidth = g_objSlider.width();
16717			
16718			if( innerEnd <  sliderWidth ){
16719				currentPosx = g_temp.startPosx + diff/3;
16720			}
16721		}
16722		
16723		if(g_temp.isDragging == false){
16724			g_temp.isDragging = true;
16725			g_objParent.trigger(g_parent.events.START_DRAG);
16726		}
16727				
16728		g_objInner.css("left", currentPosx+"px");
16729		
16730		//drag video
16731		if(g_temp.isDragVideo == true){
16732			var posDiff = currentPosx - g_temp.startPosx;
16733			var videoPosX = g_temp.videoStartX + posDiff;
16734			
16735			g_temp.videoObject.css("left", videoPosX);
16736		}
16737		
16738	}
16739	
16740	/**
16741	 * store init touch position
16742	 */
16743	function storeInitTouchData(event){
16744		
16745		var mousePos = g_functions.getMousePosition(event);
16746		
16747		g_temp.startMouseX = mousePos.pageX;
16748		
16749		//debugLine("startx:" + g_temp.startMouseX, true, true);
16750		
16751		g_temp.startMouseY = mousePos.pageY;
16752		
16753		g_temp.lastMouseX = g_temp.startMouseX;
16754		g_temp.lastMouseY = g_temp.startMouseY;
16755		g_temp.startTime = jQuery.now();
16756		
16757		var arrTouches = g_functions.getArrTouches(event);		
16758		g_temp.startArrTouches = g_functions.getArrTouchPositions(arrTouches);
16759		
16760		var objPos = g_functions.getElementSize(g_objInner);
16761		
16762		g_temp.startPosx = objPos.left;
16763		
16764		g_temp.isInitDataValid = true;
16765		
16766		//check if video object need to be dragged
16767		g_temp.isDragVideo = false;
16768					
16769		
16770		g_functions.storeEventData(event, g_temp.storedEventID);
16771	}
16772	
16773	/**
16774	 * disable touch active
16775	 */
16776	function disableTouchActive(who){
16777		
16778		g_temp.touch_active = false;
16779		
16780		//debugLine("disable: " + who, true, true);
16781	}
16782	
16783	/**
16784	 * enable the touch active
16785	 */
16786	function enableTouchActive(who, event){
16787		
16788		g_temp.touch_active = true;
16789		storeInitTouchData(event);
16790		
16791		//debugLine("enable: " + who, true, true);
16792	}
16793
16794	
16795	/**
16796	 * on touch slide start
16797	 * 
16798	 */
16799	function onTouchStart(event){
16800		
16801		event.preventDefault();
16802		
16803		g_temp.isDragging = false;
16804		
16805		//debugLine("touchstart", true, true);
16806		
16807		//check if the slides are changing from another event.
16808		if(g_parent.isAnimating() == true){
16809			g_objInner.stop(true, true);
16810		}
16811		
16812		//check num touches
16813		var arrTouches = g_functions.getArrTouches(event);
16814		if(arrTouches.length > 1){
16815			
16816			if(g_temp.touch_active == true){
16817				disableTouchActive("1");
16818			}
16819			
16820			return(true);
16821		}
16822						
16823		if(g_temp.touch_active == true){
16824			return(true);
16825		}
16826		
16827		enableTouchActive("1", event);
16828		
16829	}
16830	
16831
16832	/**
16833	 * 
16834	 * on touch move event
16835	 */
16836	function onTouchMove(event){
16837		
16838		if(g_temp.touch_active == false)
16839			return(true);
16840		
16841		//detect moving without button press
16842		if(event.buttons == 0){
16843			disableTouchActive("2");
16844			
16845			continueSlideDragChange();
16846						
16847			return(true);
16848		}
16849
16850		g_functions.updateStoredEventData(event, g_temp.storedEventID);
16851				
16852		event.preventDefault();
16853		
16854		var mousePos = g_functions.getMousePosition(event);
16855		g_temp.lastMouseX = mousePos.pageX;
16856		g_temp.lastMouseY = mousePos.pageY;
16857				
16858		//debugLine("lastX:" + g_temp.lastMouseX, true, true);
16859		
16860		var scrollDir = null;
16861		
16862		if(g_options.slider_vertical_scroll_ondrag == true)
16863			scrollDir = g_functions.handleScrollTop(g_temp.storedEventID);
16864		
16865		if(scrollDir !== "vert")
16866			handleSliderDrag(event);
16867			
16868	}
16869	
16870	/**
16871	 * on touch end event
16872	 */
16873	function onTouchEnd(event){
16874		
16875		//debugLine("touchend", true, true);
16876		
16877		var arrTouches = g_functions.getArrTouches(event);
16878		var numTouches = arrTouches.length;
16879		var isParentInPlace = g_parent.isInnerInPlace();
16880		
16881		if(isParentInPlace == true && g_temp.touch_active == false && numTouches == 0){
16882			
16883			return(true);
16884		}
16885				
16886		if(numTouches == 0 && g_temp.touch_active == true){
16887											
16888			disableTouchActive("3");
16889			
16890			var isValid = false;
16891			
16892			var wasVerticalScroll = g_functions.wasVerticalScroll(g_temp.storedEventID);
16893			
16894			if(wasVerticalScroll == false)
16895				isValid = isMovementValidForChange();
16896						
16897			if(isValid == true)
16898				continueSlideDragChange();		//change the slide
16899			else
16900				returnToPlace();	//return the inner object to place (if not in place)
16901			
16902		}else{
16903			
16904			if(numTouches == 1 && g_temp.touch_active == false){
16905								
16906				enableTouchActive("2",event);				
16907			}
16908				
16909		}
16910					
16911	}
16912
16913
16914	/**
16915	 * init touch events
16916	 */
16917	function initEvents(){
16918		
16919		//slider mouse down - drag start
16920		g_objSlider.bind("mousedown touchstart",onTouchStart);
16921		
16922		//on body move
16923		jQuery("body").bind("mousemove touchmove",onTouchMove);
16924		
16925		//on body mouse up - drag end
16926		jQuery(window).add("body").bind("mouseup touchend", onTouchEnd);
16927		
16928	}
16929	
16930	
16931	
16932	/**
16933	 * init function for avia controls
16934	 */
16935	this.init = function(objSlider, customOptions){
16936		
16937		g_parent = objSlider;
16938		g_objParent = jQuery(g_parent);
16939		g_objects = objSlider.getObjects();
16940				
16941		g_objSlider = g_objects.g_objSlider;
16942		g_objInner = g_objects.g_objInner;
16943
16944		g_options = jQuery.extend(g_options, customOptions);
16945				
16946		initEvents();
16947	}
16948	
16949	
16950	/**
16951	 * get last mouse position
16952	 */
16953	this.getLastMousePos = function(){
16954		var obj = {
16955			pageX: g_temp.lastMouseX,
16956			pageY: g_temp.lastMouseY
16957		};
16958		
16959		return(obj);
16960	}
16961	
16962	
16963	/**
16964	 * is touch active
16965	 */
16966	this.isTouchActive = function(){
16967		
16968		return(g_temp.touch_active);
16969		
16970	}
16971	
16972	
16973}
16974/**
16975 * touch thumbs control class
16976 * addon to strip gallery
16977 */
16978function UGZoomSliderControl(){
16979	
16980	var g_objSlider, g_objInner, g_parent = new UGSlider(), g_objParent;
16981	
16982	var g_functions = new UGFunctions();
16983	
16984	var t = this;
16985	
16986	var g_options = {
16987		slider_zoom_step: 1.2,							//the step of zooming with mouse wheel or zoom button
16988		slider_zoom_max_ratio: 6,						//max zoom ratio
16989		slider_zoom_return_pan_duration: 400,			//the return from pan animation duration 
16990		slider_zoom_return_pan_easing: "easeOutCubic"	//the return from pan wasing function
16991	};
16992	
16993	var g_temp = {
16994		isPanActive:false,
16995		startMouseX:0,
16996		startMouseY:0,
16997		lastMouseX:0,
16998		lastMouseY:0,
16999		startImageX:0,
17000		startImageY:0,
17001		panXActive:false,
17002		panYActive:false,
17003		objImage:null,
17004		objImageSize:null,
17005		objParent:null,
17006		objParentSize:null,
17007		objSlide:null,
17008		storeImageLastTime:0,
17009		
17010		isZoomActive: false,
17011		startDistance:0,
17012		startMiddlePoint:null,
17013		imageOrientPoint:null,
17014		objFitImageSize:null,
17015		isZoomedOnce:false
17016	};
17017
17018	
17019	/**
17020	 * init the object
17021	 */
17022	function initObject(objSlider, customOptions){
17023		
17024		g_parent = objSlider;
17025		g_objParent = jQuery(g_parent);
17026		g_objects = objSlider.getObjects();
17027		g_objSlider = g_objects.g_objSlider;
17028		g_objInner = g_objects.g_objInner;
17029		
17030		g_options = jQuery.extend(g_options, customOptions);
17031				
17032		initEvents();
17033	}
17034	
17035	
17036	/**
17037	 * get fit image to slider scale mode
17038	 * the fill become fit
17039	 */
17040	function getFitScaleMode(){
17041		
17042		var scaleMode = g_parent.getScaleMode();
17043		
17044		if(scaleMode != "down")
17045			scaleMode = "fit";
17046		
17047		return(scaleMode);
17048	}
17049	
17050	
17051	/**
17052	 * cache current slide and image
17053	 */
17054	function storeCurrentImage(){		
17055		
17056		//prevent continious image storring
17057		var currentTime = jQuery.now();
17058		var diff = currentTime - g_temp.storeImageLastTime;
17059		
17060		if(diff < 20)
17061			return(false);
17062		
17063		var slides = g_parent.getSlidesReference();
17064		g_temp.objSlide = slides.objCurrentSlide;
17065		g_temp.objImage = slides.objCurrentSlide.find("img");
17066		
17067		if(g_temp.objImage.length == 0)
17068			return(false);
17069			
17070		g_temp.objImageSize = g_functions.getElementSize(g_temp.objImage);
17071		g_temp.objParent = g_temp.objImage.parent();
17072		g_temp.objParentSize = g_functions.getElementSize(g_temp.objParent);
17073		
17074		var scaleMode = getFitScaleMode();
17075		
17076		objPadding = g_parent.getObjImagePadding();
17077		
17078		g_temp.objFitImageSize = g_functions.getImageInsideParentDataByImage(g_temp.objImage, scaleMode, objPadding);
17079		
17080		var currentTime = jQuery.now();
17081		g_temp.storeImageLastTime = currentTime;
17082		
17083		return(true);
17084	}
17085	
17086	
17087	/**
17088	 * zoom current image
17089	 * mode: in, out, back
17090	 */
17091	function zoomCurrentImage(mode, mousePos){
17092		
17093		var slides = g_parent.getSlidesReference();
17094		var objImage = slides.objCurrentSlide.find("img");
17095		var scaleMode = getFitScaleMode();
17096		
17097		g_objParent.trigger(g_parent.events.ZOOM_START);
17098		
17099		//flag if the images zoomed
17100		var isZoomed = true;
17101		
17102		var objPadding = g_parent.getObjImagePadding();
17103				
17104		if(mode == "back"){	
17105			var objOriginalSize = g_functions.getImageOriginalSize(objImage);
17106			g_functions.scaleImageFitParent(objImage, objOriginalSize.width, objOriginalSize.height, scaleMode, objPadding);
17107		}
17108		else{			
17109			var zoomIn = (mode == "in")?true:false;
17110			
17111			isZoomed = g_functions.zoomImageInsideParent(objImage, zoomIn, g_options.slider_zoom_step, mousePos, scaleMode, g_options.slider_zoom_max_ratio, objPadding);
17112		}
17113		
17114		if(isZoomed == true){
17115			g_objParent.trigger(g_parent.events.ZOOMING);
17116			g_objParent.trigger(g_parent.events.ZOOM_CHANGE);
17117			g_objParent.trigger(g_parent.events.ZOOM_END);
17118		}
17119		
17120	}
17121	
17122	
17123	function ____________PAN_____________(){};
17124	
17125	
17126	/**
17127	 * check if pan is posible for the current image
17128	 * check if the image is bigger then the parent
17129	 */
17130	function isPanPosible(objImage, event, stictTouchesCheck){
17131		
17132		//check num touches, strict means that even if 0 - pan not posible
17133		var arrTouches = g_functions.getArrTouches(event);
17134		
17135		if(stictTouchesCheck === true){
17136			
17137			if(arrTouches.length != 1)
17138				return(false);			
17139		}else{
17140			if(arrTouches.length > 1)
17141				return(false);			
17142		}
17143		
17144		if(g_functions.isElementBiggerThenParent(objImage))
17145			return(true);
17146		
17147		return(false);
17148	}
17149	
17150	
17151	/**
17152	 * store pan values
17153	 */
17154	function storePanInitValues(event){
17155		
17156		var mousePos = g_functions.getMousePosition(event);
17157		
17158		g_temp.startMouseX = mousePos.pageX;
17159		g_temp.startMouseY = mousePos.pageY;
17160		
17161		g_temp.lastMouseX = g_temp.startMouseX;
17162		g_temp.lastMouseY = g_temp.startMouseY;
17163		
17164		g_temp.startImageX = g_temp.objImageSize.left;
17165		g_temp.startImageY = g_temp.objImageSize.top;
17166		
17167		g_temp.panXActive = (g_temp.objImageSize.width > g_temp.objParentSize.width);
17168		g_temp.panYActive = (g_temp.objImageSize.height > g_temp.objParentSize.height);
17169		
17170	}
17171	
17172	
17173	/**
17174	 * check pan start, and start if posible
17175	 */
17176	function startPan(event){
17177				
17178		g_temp.isPanActive = true;
17179		storePanInitValues(event);
17180		
17181	}
17182	
17183	
17184	/**
17185	 * pan the image
17186	 */
17187	function panImage(event){
17188		
17189		if(g_temp.objImage == undefined || g_temp.objImage.length == 0)
17190			return(true);
17191		
17192		var mousePos = g_functions.getMousePosition(event);
17193		
17194		var diffX = mousePos.pageX - g_temp.startMouseX;
17195		var diffY = mousePos.pageY - g_temp.startMouseY;
17196		
17197		//get active direction
17198		var diffLastX = mousePos.pageX - g_temp.lastMouseX;
17199		var diffLastY = mousePos.pageY - g_temp.lastMouseY;
17200		
17201		var directionX = (diffLastX < 0) ? "left":"right";
17202		var directionY = (diffLastY < 0) ? "up":"down";
17203		
17204		g_temp.lastMouseX = mousePos.pageX;
17205		g_temp.lastMouseY = mousePos.pageY;
17206		
17207		var posImage = g_functions.getElementSize(g_temp.objImage);
17208		
17209		//var imageX = g_temp.startImageX + diffX;
17210		//var imageY = g_temp.startImageY + diffY;
17211				
17212		
17213		//slow down if no pan available in this point
17214		//slow down y
17215		
17216		if(g_temp.panYActive == false){
17217			
17218			diffLastY = 0;
17219			
17220		}else{		//zoom enabled
17221			
17222			if(directionY == "down" && posImage.top > 0){			
17223				
17224				diffLastY = diffLastY / 3;				
17225				
17226			}else if(directionY == "up" && posImage.bottom < g_temp.objParentSize.height){
17227				
17228				diffLastY = diffLastY / 3;				
17229				
17230			}
17231		}
17232		
17233		//slow down x (only if the pan enabled)
17234		if(g_temp.panXActive == false || g_parent.isInnerInPlace() == false){
17235			
17236			diffLastX = 0;
17237		
17238		}else{	//zoom enabled
17239			
17240			if(directionX == "right" && posImage.left > 0){				
17241				diffLastX = diffLastX / 3;				
17242			}
17243			else if(directionX == "left" && posImage.right < g_temp.objParentSize.width){
17244				diffLastX = diffLastX / 3;
17245			}
17246	    }
17247		
17248		var imageX = posImage.left + diffLastX;
17249		var imageY = posImage.top + diffLastY;
17250		
17251		
17252		g_functions.placeElement(g_temp.objImage, imageX, imageY);
17253		
17254	}
17255	
17256	
17257	
17258	
17259	/**
17260	 * return the image to place if it's out of borders
17261	 */
17262	function checkReturnAfterPan(){
17263				
17264		var isReturnX = false, isReturnY = false, newX = 0, newY = 0;
17265		var objSize = g_functions.getElementSize(g_temp.objImage);
17266		var objImagePadding = g_parent.getObjImagePadding();
17267				
17268		var objCenterPos = g_functions.getElementCenterPosition(g_temp.objImage, objImagePadding);
17269		
17270		g_temp.panXActive = (g_temp.objImageSize.width > g_temp.objParentSize.width);
17271		g_temp.panYActive = (g_temp.objImageSize.height > g_temp.objParentSize.height);
17272				
17273		
17274		if(g_temp.panYActive == true){
17275			
17276			if(objSize.top > 0){		//off limit top
17277				
17278				newY = 0;
17279				isReturnY = true;
17280				
17281			}else if(objSize.bottom < g_temp.objParentSize.height){		//off limit bottom
17282				
17283				newY = g_temp.objParentSize.height - objSize.height;
17284				isReturnY = true;
17285				
17286			}
17287			
17288		}else{		//pan not active y - return to center
17289			
17290			if(objSize.top != objCenterPos.top){
17291				isReturnY = true;
17292				newY = objCenterPos.top;
17293			}
17294			
17295		}
17296		
17297		
17298		//check return x to place
17299		if(g_temp.panXActive == true){
17300			
17301			if(objSize.left > 0){		//off limit left
17302				
17303				newX = 0;
17304				isReturnX = true;
17305				
17306			}else if(objSize.right < g_temp.objParentSize.width){		//off limit right
17307								
17308				newX = g_temp.objParentSize.width - objSize.width;
17309				isReturnX = true;
17310				
17311			}
17312			
17313		}else{		//pan not active x - return to center
17314			
17315		//	debugLine("not active", true);
17316			
17317			if(objSize.left != objCenterPos.left){
17318				isReturnX = true;
17319				newX = objCenterPos.left;
17320			}
17321		}
17322		
17323		
17324		//do the animation
17325		var objCss = {};
17326		if(isReturnY == true)
17327			objCss.top = newY + "px";
17328		
17329		if(isReturnX == true)
17330			objCss.left = newX + "px";
17331		
17332		
17333		if(isReturnY == true || isReturnX == true){
17334						
17335			g_temp.objImage.animate(objCss,{
17336				duration: g_options.slider_zoom_return_pan_duration,
17337				easing: g_options.slider_zoom_return_pan_easing,
17338				queue: false
17339			});
17340
17341		}
17342		
17343	}
17344	
17345	/**
17346	 * check if the image animating or not
17347	 */
17348	function isImageAnimating(){
17349		
17350		if(g_temp.objImage && g_temp.objImage.is(":animated"))
17351			return(true);
17352		
17353		return(false);
17354	}
17355	
17356	function ____________END_PAN_____________(){};
17357	
17358	function ________TOUCH_ZOOM_____________(){};
17359	
17360	/**
17361	 * start touch zoom
17362	 */
17363	function startTouchZoom(arrTouches){
17364				
17365		g_temp.isZoomActive = true;
17366		
17367		//store init diff
17368		g_temp.startDistance = g_functions.getDistance(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY);
17369		if(g_temp.startDistance == 0)
17370			g_temp.startDistance = 1;
17371		
17372		
17373		//store init positions
17374		g_temp.startMiddlePoint = g_functions.getMiddlePoint(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY);
17375				
17376		g_temp.objImageSize = g_functions.getElementSize(g_temp.objImage);
17377			
17378		g_temp.startImageX = g_temp.objImageSize.left;
17379		g_temp.startImageY = g_temp.objImageSize.top;
17380		
17381		//set orient point
17382		g_temp.imageOrientPoint = g_functions.getElementLocalPoint(g_temp.startMiddlePoint, g_temp.objImage);
17383		
17384		var isInsideImage = g_functions.isPointInsideElement(g_temp.imageOrientPoint, g_temp.objImageSize);
17385		if(isInsideImage == false){
17386			g_temp.imageOrientPoint = g_functions.getElementCenterPoint(g_temp.objImage);
17387		}
17388		
17389		//trigger start zoom event
17390		g_objParent.trigger(g_parent.events.ZOOM_START);
17391	}
17392	
17393	
17394	/**
17395	 * check num touches, if not 2 - end zoom
17396	 */
17397	function checkTouchZoomEnd(event){
17398				
17399		if(g_temp.isZoomActive == false)
17400			return(false);
17401		
17402		var arrTouches = g_functions.getArrTouches(event);			
17403		if(arrTouches.length != 2){		//end touch zoom
17404			
17405			g_temp.isZoomActive = false;
17406			
17407			//trigger end zoom event
17408			g_objParent.trigger(g_parent.events.ZOOM_END);			
17409		}	
17410		
17411	}
17412	
17413	
17414	/**
17415	 * check start touch zoom
17416	 */
17417	function checkTouchZoomStart(event){
17418				
17419		if(g_temp.isZoomActive == true)
17420			return(true);
17421
17422
17423		var arrTouches = g_functions.getArrTouches(event);
17424				
17425		if(arrTouches.length != 2)
17426			return(true);
17427					
17428		startTouchZoom(arrTouches);		
17429	}
17430	
17431	
17432	/**
17433	 * do touch zoom on touch devices
17434	 */
17435	function doTouchZoom(event){
17436				
17437		var arrTouches = g_functions.getArrTouches(event);
17438				
17439		var distance = g_functions.getDistance(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY);		
17440		var zoomRatio = distance / g_temp.startDistance;
17441		
17442		var middlePoint = g_functions.getMiddlePoint(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY);
17443		
17444		//set zoom data:
17445		var newWidth = g_temp.objImageSize.width * zoomRatio;
17446		var newHeight = g_temp.objImageSize.height * zoomRatio;
17447		
17448		//check max zoom ratio:
17449		var objOriginalSize = g_functions.getImageOriginalSize(g_temp.objImage);
17450		var expectedZoomRatio = 1;		
17451		if(objOriginalSize.width > 0)
17452			expectedZoomRatio = newWidth / objOriginalSize.width;
17453		
17454		if(expectedZoomRatio > g_options.slider_zoom_max_ratio)
17455			return(true);
17456		
17457		//set pan data:
17458		panX = -(g_temp.imageOrientPoint.x * zoomRatio - g_temp.imageOrientPoint.x);
17459		panY = -(g_temp.imageOrientPoint.y * zoomRatio - g_temp.imageOrientPoint.y);
17460		
17461		var diffMiddleX = (middlePoint.x - g_temp.startMiddlePoint.x);
17462	    var diffMiddleY = (middlePoint.y - g_temp.startMiddlePoint.y);
17463		
17464	    var posx = g_temp.startImageX + panX + diffMiddleX;
17465		var posy = g_temp.startImageY + panY + diffMiddleY;		
17466				
17467		
17468		//resize and place:
17469		g_functions.setElementSizeAndPosition(g_temp.objImage, posx, posy, newWidth, newHeight);
17470		
17471		//trigger zooming event
17472		g_objParent.trigger(g_parent.events.ZOOMING);			
17473		g_objParent.trigger(g_parent.events.ZOOM_CHANGE);			
17474
17475		/*
17476		debugLine({
17477			middleStartX: g_temp.startMiddlePoint.x,
17478			middleX: middlePoint.x,
17479			diffMiddleX: diffMiddleX
17480		});
17481		*/
17482		
17483	}
17484	
17485	
17486	/**
17487	 * check return the image from zoom
17488	 */
17489	function checkReturnFromZoom(){
17490				
17491		if(g_temp.objImage == undefined || g_temp.objImage.length == 0)
17492			return(true);
17493		
17494		var objSize = g_functions.getElementSize(g_temp.objImage);
17495		
17496		if(objSize.width < g_temp.objFitImageSize.imageWidth){
17497			
17498			g_temp.objImage.css({
17499				position:"absolute",
17500				margin:"none"
17501			});
17502			
17503			var objCss = {
17504				top: g_temp.objFitImageSize.imageTop + "px",
17505				left: g_temp.objFitImageSize.imageLeft + "px",
17506				width: g_temp.objFitImageSize.imageWidth + "px",
17507				height: g_temp.objFitImageSize.imageHeight + "px"
17508			};
17509			
17510			g_temp.objImage.animate(objCss,{
17511				duration: g_options.slider_zoom_return_pan_duration,
17512				easing: g_options.slider_zoom_return_pan_easing,
17513				queue: false
17514			});
17515			
17516		}else{			
17517			checkReturnAfterPan();
17518		}
17519		
17520	}
17521	
17522	
17523	function ________END_TOUCH_ZOOM_____________(){};
17524	
17525	
17526	/**
17527	 * 
17528	 * touch start event - start pan, remember start pan data
17529	 */
17530	function onTouchStart(event){
17531		
17532		//if no image type, exit
17533		if(g_parent.isCurrentSlideType("image") == false)
17534			return(true);
17535		
17536		var isStored = storeCurrentImage();
17537		
17538		if(g_temp.objImage == undefined || g_temp.objImage.length == 0)
17539			return(true);
17540		
17541		event.preventDefault();
17542						
17543		//stop animation if exists
17544		if(isImageAnimating() == true){			
17545			g_temp.objImage.stop(true);
17546		}
17547		
17548		if(g_temp.isZoomActive == true){
17549			
17550			checkTouchZoomEnd(event);
17551			
17552		}else{
17553			
17554			checkTouchZoomStart(event);
17555			
17556		}
17557		
17558		//if zoom started stop panning, if not, start panning
17559		if(g_temp.isZoomActive == true){
17560			
17561			g_temp.isPanActive = false;
17562		
17563		}else if(isPanPosible(g_temp.objImage, event) == true && g_temp.isZoomedOnce == true){
17564			
17565			startPan(event);
17566		}
17567		
17568		/*
17569		debugLine({
17570				pan: g_temp.isPanActive,
17571				zoom: g_temp.isZoomActive,
17572				event: "start"
17573			}, true);
17574		*/
17575		
17576	}
17577	
17578	
17579	/**
17580	 * touch end event - bring the image to place
17581	 */
17582	function onTouchEnd(event){
17583		
17584		if(g_parent.isCurrentSlideType("image") == false)
17585			return(true);
17586		
17587		//check if some gallery button clicked
17588		var objTarget = jQuery(event.target);
17589		if(objTarget.data("ug-button") == true){
17590			//event.preventDefault();
17591			return(false);
17592		}
17593		
17594		var isStored = storeCurrentImage();
17595
17596		if(g_temp.objImage == undefined || g_temp.objImage.length == 0)
17597			return(true);
17598				
17599		var panWasActive = g_temp.isPanActive;
17600		var zoomWasActive = g_temp.isZoomActive;
17601		
17602		//if the inner not in place, don't return noting, let the slide change
17603		if(g_parent.isInnerInPlace() == false){
17604			g_temp.isZoomActive = false;
17605			g_temp.isPanActive = false;
17606			return(true);
17607		}
17608		
17609		//check end zoom
17610		if(g_temp.isZoomActive == true){
17611			checkTouchZoomEnd(event);
17612		}else{
17613			checkTouchZoomStart(event);
17614		}
17615		
17616		
17617		if(g_temp.isZoomActive == true){
17618			
17619			g_temp.isPanActive = false;
17620			
17621		}else{
17622			
17623			var panPosible = isPanPosible(g_temp.objImage, event, true);
17624			
17625			if(g_temp.isPanActive == true ){
17626						
17627				g_temp.isPanActive = false;
17628				
17629			}else if(panPosible == true){
17630				
17631				startPan(event);
17632			}
17633			
17634		}
17635		
17636		/*
17637		debugLine({
17638			pan:g_temp.isPanActive,
17639			zoom: g_temp.isZoomActive
17640		}, true);
17641		*/
17642		
17643		if((panWasActive || zoomWasActive) && g_temp.isZoomActive == false && g_temp.isPanActive == false){
17644			checkReturnFromZoom();
17645		}
17646		
17647		
17648	}
17649	
17650	
17651	/**
17652	 * 
17653	 * touch move event - pan
17654	 */
17655	function onTouchMove(event){
17656		
17657		if(g_parent.isCurrentSlideType("image") == false)
17658			return(true);
17659				
17660		//check touch zoom (pinch gesture)
17661		if(g_temp.isZoomActive == true){
17662			
17663			doTouchZoom(event);
17664			
17665		}else if(g_temp.isPanActive == true){
17666			
17667			panImage(event);
17668			
17669		}
17670		
17671		
17672	}
17673	
17674	
17675	/**
17676	 * on slider mousewheel event
17677	 */
17678	function onSliderMouseWheel(event, delta, deltaX, deltaY){
17679		
17680		if(g_options.slider_zoom_mousewheel == false)
17681			return(true);
17682		
17683		if(g_parent.isCurrentSlideType("image") == false)
17684			return(true);
17685		
17686		event.preventDefault();
17687		
17688		//prevent default only if needed
17689		//if(zoomIn == true || zoomIn == false && g_functions.isElementBiggerThenParent(objImage))
17690		//event.preventDefault();
17691		
17692		
17693		var zoomIn = (delta > 0);
17694		var mousePos = g_functions.getMousePosition(event);
17695		var	mode = (zoomIn == true) ? "in":"out";
17696		
17697		zoomCurrentImage(mode, mousePos);
17698	}
17699	
17700	
17701	/**
17702	 * init touch events
17703	 */
17704	function initEvents(){
17705		
17706		//debugLine("init");
17707		g_objSlider.on("mousewheel",onSliderMouseWheel);
17708		
17709		//slider mouse down - pan start
17710		g_objSlider.bind("mousedown touchstart",onTouchStart);
17711		
17712		//on body move
17713		jQuery("body").bind("mousemove touchmove",onTouchMove);
17714		
17715		//on body mouse up - pan end
17716		jQuery(window).add("body").bind("mouseup touchend", onTouchEnd);
17717		
17718		//event before image returned to init position
17719		g_objParent.bind(g_parent.events.BEFORE_RETURN, function(){
17720			
17721			checkReturnFromZoom();
17722		});
17723				
17724		//on item change update isZoomedOnce event. Allow panning only if zoomed once
17725		g_objParent.bind(g_parent.events.ITEM_CHANGED, function(){
17726			g_temp.isZoomedOnce = false;
17727		});
17728		
17729		g_objParent.bind(g_parent.events.ZOOM_CHANGE, function(){
17730			g_temp.isZoomedOnce = true;
17731		});
17732		
17733	}
17734	
17735	this.________EXTERNAL_____________ = function(){};
17736	
17737	/**
17738	 * check if the image is zoomed, and there is a place for left panning
17739	 */
17740	this.isPanEnabled = function(event, direction){
17741		
17742		storeCurrentImage();
17743		
17744		if(g_temp.objImage == undefined || g_temp.objImage.length == 0)
17745			return(false);
17746		
17747		if(g_temp.isZoomedOnce == false)
17748			return(false);
17749		
17750		if(isPanPosible(g_temp.objImage, event) == false)
17751			return(false);
17752		
17753		if(g_parent.isInnerInPlace() == false)
17754			return(false);
17755		
17756		if(direction == "left"){
17757			
17758			if(g_temp.objImageSize.right <= g_temp.objParentSize.width)
17759				return(false);
17760			
17761		}else{	//right direction
17762			
17763			if(g_temp.objImageSize.left >= 0)
17764				return(false);
17765		}
17766		
17767		return(true);
17768	}
17769	
17770	
17771	/**
17772	 * init function for avia controls
17773	 */
17774	this.init = function(objSlider, customOptions){
17775		
17776		initObject(objSlider, customOptions);
17777	}
17778	
17779	/**
17780	 * zoom in
17781	 */
17782	this.zoomIn = function(){		
17783		zoomCurrentImage("in");	
17784	}
17785	
17786	/**
17787	 * zoom out
17788	 */
17789	this.zoomOut = function(){		
17790		zoomCurrentImage("out");		
17791	}
17792	
17793	/**
17794	 * zoom back
17795	 */
17796	this.zoomBack = function(){
17797		
17798		zoomCurrentImage("back");		
17799	}
17800}
17801/** -------------- Wistia API ---------------------*/
17802
17803function UGWistiaAPI(){
17804	
17805	this.isAPILoaded = false;
17806	var t = this, g_objThis = jQuery(this), g_intHandle;
17807	var g_player, g_isPlayerReady = false;
17808	
17809	this.events = {
17810			START_PLAYING: "start_playing",
17811			STOP_PLAYING: "stop_playing",
17812			VIDEO_ENDED: "video_ended"
17813	};
17814
17815	
17816	/**
17817	 * check if sound cloud active
17818	 */
17819	function isWistiaActive(){
17820		
17821		return(typeof Wistia != "undefined");	
17822	}
17823	
17824	/**
17825	 * load vimeo API
17826	 */
17827	this.loadAPI = function(){
17828		
17829		if(g_ugWistiaAPI.isAPILoaded == true)
17830			return(true);
17831
17832		if(isWistiaActive()){
17833			g_ugWistiaAPI.isAPILoaded = true;
17834			return(true);
17835		}
17836		
17837		g_ugFunctions.loadJs("fast.wistia.com/assets/external/E-v1.js", true);
17838		
17839		g_ugWistiaAPI.isAPILoaded = true;		
17840	}
17841
17842	
17843	/**
17844	 * actually put the video
17845	 */
17846	function putVideoActually(divID, videoID, width, height, isAutoplay){
17847		
17848		g_player = null;
17849		g_isPlayerReady = false;
17850		
17851		var htmlID = divID + "_video";
17852		
17853		var html = "<div id='"+htmlID+"' class='wistia_embed' style='width:"+width+";height:"+height+";' data-video-width='"+width+"' data-video-height='"+height+"'>&nbsp;</div>";
17854				
17855		jQuery("#"+divID).html(html);
17856		
17857		g_player = Wistia.embed(videoID, {
17858			  version: "v1",
17859			  videoWidth: width,
17860			  videoHeight: height,
17861			  container: htmlID,
17862			  autoPlay: isAutoplay
17863		});
17864				
17865		g_isPlayerReady = true;
17866				
17867		initEvents();
17868	}
17869	
17870	
17871	/**
17872	 * init events
17873	 */
17874	function initEvents(){
17875		
17876		//set "play" event
17877		
17878		g_player.bind('play', function(){
17879			g_objThis.trigger(t.events.START_PLAYING);
17880		});
17881		
17882		//set "pause event"
17883		g_player.bind('pause', function(){
17884			g_objThis.trigger(t.events.STOP_PLAYING);
17885		});
17886		
17887		g_player.bind('end', function(){
17888			g_objThis.trigger(t.events.STOP_PLAYING);
17889			g_objThis.trigger(t.events.VIDEO_ENDED);
17890		});
17891		
17892	}
17893	
17894	
17895	/**
17896	 * do some command
17897	 */
17898	this.doCommand = function(command){
17899		
17900		if(g_player == null)
17901			return(false);
17902		
17903		if(g_isPlayerReady == false)
17904			return(false);
17905		
17906		switch(command){
17907			case "play":
17908				g_player.play();
17909			break;
17910			case "pause":
17911				g_player.pause();
17912			break;		
17913		}
17914		
17915	}
17916	
17917	/**
17918	 * do pause command
17919	 */
17920	this.pause = function(){
17921		t.doCommand("pause");
17922	}
17923	
17924	/**
17925	 * do play command
17926	 */
17927	this.play = function(){
17928		t.doCommand("play");
17929	}
17930	
17931	
17932	/**
17933	 * put the vimeo video
17934	 */
17935	this.putVideo = function(divID, videoID, width, height, isAutoplay){
17936		
17937		if(isWistiaActive()){
17938			putVideoActually(divID, videoID, width, height, isAutoplay);
17939			return(true);
17940		}
17941		
17942		
17943		//if no API present, wait for the API being ready
17944		this.loadAPI();
17945		g_intHandle = setInterval(function(){
17946			
17947			if(isWistiaActive()){
17948				putVideoActually(divID, videoID, width, height, isAutoplay);
17949				clearInterval(g_intHandle);
17950			}
17951			
17952		}, 500);
17953		
17954	}
17955	
17956	
17957	/**
17958	 * get if the player is ready
17959	 */
17960	this.isPlayerReady = function(){
17961				
17962		if(g_isPlayerReady && g_player)
17963			return(true);
17964	
17965		return(false);
17966	}	
17967	
17968	
17969}
17970
17971/** -------------- Sound Cloud API ---------------------*/
17972
17973function UGSoundCloudAPI(){
17974	
17975	this.isAPILoaded = false;
17976	var t = this, g_objThis = jQuery(this), g_intHandle;
17977	var g_player, g_lastContainerID;
17978	
17979	this.events = {
17980			START_PLAYING: "start_playing",
17981			STOP_PLAYING: "stop_playing",
17982			VIDEO_ENDED: "video_ended"
17983	};
17984
17985	/**
17986	 * check if sound cloud active
17987	 */
17988	function isSCActive(){
17989		
17990		return(typeof SC != "undefined");	
17991	}
17992	
17993	/**
17994	 * load vimeo API
17995	 */
17996	this.loadAPI = function(){
17997		
17998		if(g_ugSoundCloudAPI.isAPILoaded == true)
17999			return(true);
18000				
18001		if(isSCActive()){
18002			g_ugSoundCloudAPI.isAPILoaded = true;
18003			return(true);
18004		}
18005		
18006		g_ugFunctions.loadJs("w.soundcloud.com/player/api.js", true);
18007		
18008		g_ugSoundCloudAPI.isAPILoaded = true;		
18009	}
18010	
18011	/**
18012	 * actually put the video
18013	 */
18014	function putSoundActually(divID, trackID, width, height, isAutoplay){
18015		
18016		g_player = null;
18017		g_isPlayerReady = false;
18018		
18019		var iframeID = divID+"_iframe";
18020		
18021		var url = location.protocol+"//w.soundcloud.com/player/?url=http://api.soundcloud.com/tracks/"+trackID;
18022		url += "&amp;buying=false&amp;liking=false&amp;download=false&amp;sharing=false&amp;show_artwork=true&show_comments=false&amp;show_playcount=true&amp;show_user=false&amp;hide_related=true&amp;visual=true&amp;start_track=0&amp;callback=true";
18023		
18024		if(isAutoplay === true)
18025			url += "&amp;auto_play=true";
18026		else
18027			url += "&amp;auto_play=false";
18028		
18029		var html = "<iframe id='"+iframeID+"' src="+url+" width='"+width+"' height='"+height+"' frameborder='0' scrolling='no' webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>";
18030		
18031		jQuery("#"+divID).html(html);
18032		
18033		//get the player object
18034		g_player = SC.Widget(iframeID);
18035		
18036		g_player.bind(SC.Widget.Events.READY, function() {
18037			
18038			if(g_player){
18039				g_isPlayerReady = true;
18040				initEvents();
18041			}
18042			
18043		});
18044		
18045		g_lastContainerID = divID;
18046	}
18047
18048	
18049	/**
18050	 * init events
18051	 */
18052	function initEvents(){
18053		
18054		
18055		//set "play" event
18056		g_player.bind(SC.Widget.Events.PLAY, function(){
18057			g_objThis.trigger(t.events.START_PLAYING);
18058		});
18059		
18060		//set "pause event"
18061		g_player.bind(SC.Widget.Events.PAUSE, function(){
18062			g_objThis.trigger(t.events.STOP_PLAYING);
18063		});
18064		
18065		g_player.bind(SC.Widget.Events.FINISH, function(){
18066			g_objThis.trigger(t.events.STOP_PLAYING);
18067			g_objThis.trigger(t.events.VIDEO_ENDED);
18068		});
18069		
18070	}
18071		
18072	
18073	/**
18074	 * put the youtube video
18075	 */
18076	this.putSound = function(divID, trackID, width, height, isAutoplay){
18077		
18078		if(isSCActive()){
18079			putSoundActually(divID, trackID, width, height, isAutoplay);
18080			return(true);
18081		}
18082		
18083		
18084		//if no API present, wait for the API being ready
18085		this.loadAPI();
18086		g_intHandle = setInterval(function(){
18087			
18088			if(isSCActive()){
18089				putSoundActually(divID, trackID, width, height, isAutoplay);
18090				clearInterval(g_intHandle);
18091			}
18092			
18093		}, 500);
18094		
18095	}
18096	
18097
18098	/**
18099	 * do some command
18100	 */
18101	this.doCommand = function(command){
18102		
18103		if(g_player == null)
18104			return(false);
18105		
18106		if(g_isPlayerReady == false)
18107			return(false);
18108		
18109		switch(command){
18110			case "play":
18111				g_player.play();
18112			break;
18113			case "pause":
18114				g_player.pause();
18115			break;
18116		}
18117		
18118	}	
18119	
18120	
18121	/**
18122	 * pause video
18123	 */
18124	this.pause = function(){
18125		t.doCommand("pause");
18126	}
18127	
18128	
18129	/**
18130	 * play video
18131	 */
18132	this.play = function(){
18133		t.doCommand("play");
18134	}
18135	
18136	/**
18137	 * destroy the player
18138	 */
18139	this.destroy = function(){
18140		
18141		g_isPlayerReady = false;
18142		g_player = null;
18143		
18144		if(g_lastContainerID){
18145			jQuery("#" + g_lastContainerID).html("");
18146			g_lastContainerID = null;
18147		}
18148		
18149	}
18150	
18151}
18152
18153/** -------------- html5 Video API ---------------------*/
18154
18155function UGHtml5MediaAPI(){
18156	
18157	this.isAPILoaded = false;
18158	var t = this, g_objThis = jQuery(this), g_intHandle;
18159	var g_player;
18160	
18161	this.events = {
18162			START_PLAYING: "start_playing",
18163			STOP_PLAYING: "stop_playing",
18164			VIDEO_ENDED: "video_ended"
18165	};
18166	
18167	/**
18168	 * load vimeo API
18169	 */
18170	this.loadAPI = function(){
18171		
18172		if(g_ugHtml5MediaAPI.isAPILoaded == true)
18173			return(true);
18174		
18175		
18176		if(isMediaElementActive()){
18177			g_ugHtml5MediaAPI.isAPILoaded = true;
18178			return(true);
18179		}
18180		
18181		g_ugFunctions.loadJs("cdnjs.cloudflare.com/ajax/libs/mediaelement/2.18.1/mediaelement.min.js", true);
18182		g_ugFunctions.loadCss("cdnjs.cloudflare.com/ajax/libs/mediaelement/2.18.1/mediaelementplayer.min.css", true);
18183		
18184		g_ugHtml5MediaAPI.isAPILoaded = true;		
18185	}
18186	
18187	/**
18188	 * return true if the mediaelement is active
18189	 */
18190	function isMediaElementActive(){
18191				
18192		return(typeof mejs != "undefined");
18193	}
18194	
18195	
18196	/**
18197	 * actually put the video
18198	 */
18199	function putVideoActually(divID, data, width, height, isAutoplay){
18200		
18201		g_player = null;
18202		g_isPlayerReady = false;
18203		
18204		var urlFlash = location.protocol + "//cdnjs.cloudflare.com/ajax/libs/mediaelement/2.18.1/flashmediaelement-cdn.swf";
18205		var urlSilverlight = location.protocol + "//cdnjs.cloudflare.com/ajax/libs/mediaelement/2.18.1/silverlightmediaelement.xap";
18206
18207		var htmlID = divID + "_video";
18208		var htmlAutoplay = "";
18209		if(isAutoplay && isAutoplay === true)
18210			htmlAutoplay = "autoplay='autoplay'"
18211		
18212		var htmlPoster = "";
18213		if(data.posterImage)
18214			htmlPoster = "poster='"+data.posterImage+"'";
18215		
18216		var html = "<video id='"+htmlID+"' width='"+width+"' height='"+height+"'  controls='controls' preload='none' "+htmlAutoplay+" "+htmlPoster+">";
18217				
18218		if(data.mp4 != "")
18219			html += "<source type='video/mp4' src='"+data.mp4+"' />";
18220		
18221		if(data.webm != "")
18222			html += "<source type='video/webm' src='"+data.webm+"' />";
18223
18224		if(data.ogv != "")
18225			html += "<source type='video/ogg' src='"+data.ogv+"' />";
18226		 
18227		html +=  "<object width='"+width+"' height='"+height+"' type='application/x-shockwave-flash' data='"+urlFlash+"'>";
18228		html +=  "<param name='movie' value='"+urlFlash+"' />";
18229		html +=  "<param name='flashvars' value='controls=true&file="+data.mp4+"' />";
18230		html +=  "</object>";
18231		
18232		html += "</video>";
18233		
18234		jQuery("#"+divID).html(html);
18235		
18236		new MediaElement(htmlID, {			
18237		    enablePluginDebug: false,
18238		    flashName: urlFlash,
18239		    silverlightName: urlSilverlight,
18240		    success: function (mediaElement, domObject) { 
18241		    	g_isPlayerReady = true;
18242		    	g_player = mediaElement;
18243		    			    	
18244		    	if(isAutoplay == false)
18245		    		g_player.pause();
18246		    	
18247		    	initEvents();
18248		    },
18249		    error: function (objError) { 
18250		    	trace(objError);
18251		    }
18252		});		
18253		
18254	}
18255	
18256	
18257	/**
18258	 * init player events function
18259	 */
18260	function initEvents(){
18261		
18262		g_ugFunctions.addEvent(g_player, "play", function(){
18263			g_objThis.trigger(t.events.START_PLAYING);
18264		});
18265		
18266		g_ugFunctions.addEvent(g_player, "pause", function(){
18267			g_objThis.trigger(t.events.STOP_PLAYING);
18268		});
18269		
18270		g_ugFunctions.addEvent(g_player, "ended", function(){
18271			g_objThis.trigger(t.events.STOP_PLAYING);
18272			g_objThis.trigger(t.events.VIDEO_ENDED);
18273		});
18274		
18275	}
18276	
18277	
18278	/**
18279	 * put the vimeo video
18280	 */
18281	this.putVideo = function(divID, data, width, height, isAutoplay){
18282		
18283		if(isMediaElementActive()){
18284			putVideoActually(divID, data, width, height, isAutoplay);
18285			return(true);
18286		}
18287		
18288		
18289		//if no API present, wait for the API being ready
18290		this.loadAPI();
18291		g_intHandle = setInterval(function(){
18292			
18293			if(isMediaElementActive()){
18294				putVideoActually(divID, data, width, height, isAutoplay);
18295				clearInterval(g_intHandle);
18296			}
18297			
18298		}, 500);
18299		
18300	}
18301
18302	/**
18303	 * do some command
18304	 */
18305	this.doCommand = function(command){
18306				
18307		if(g_player == null)
18308			return(false);
18309		
18310		if(g_isPlayerReady == false)
18311			return(false);
18312		
18313		switch(command){
18314			case "play":
18315				g_player.play();
18316			break;
18317			case "pause":
18318				g_player.pause();
18319			break;
18320		}
18321		
18322	}	
18323	
18324	
18325	/**
18326	 * pause video
18327	 */
18328	this.pause = function(){
18329		t.doCommand("pause");
18330	}
18331	
18332	
18333	/**
18334	 * play video
18335	 */
18336	this.play = function(){
18337		t.doCommand("play");
18338	}
18339	
18340}
18341
18342
18343/** -------------- Vimeo API class ---------------------*/
18344
18345function UGVimeoAPI(){
18346	
18347	this.isAPILoaded = false;
18348	
18349	var t = this, g_objThis = jQuery(this), g_intHandle;
18350	var g_player = null, g_isPlayerReady = false, g_lastCotnainerID, g_cueChangeAutoplay = false;
18351	
18352	
18353	this.events = {
18354			START_PLAYING: "start_playing",
18355			STOP_PLAYING: "stop_playing",
18356			VIDEO_ENDED: "video_ended"
18357	};
18358	
18359	/**
18360	 * load vimeo API
18361	 */
18362	this.loadAPI = function(){
18363		
18364		if(g_ugVimeoAPI.isAPILoaded == true)
18365			return(true);
18366		
18367		if(isFroogaloopActive()){
18368			g_ugVimeoAPI.isAPILoaded = true;
18369			return(true);
18370		}
18371
18372		g_ugFunctions.loadJs("f.vimeocdn.com/js/froogaloop2.min.js", true);
18373		
18374		g_ugVimeoAPI.isAPILoaded = true;		
18375	}
18376	
18377	
18378	
18379	/**
18380	 * tells if the froogaloop library active
18381	 */
18382	function isFroogaloopActive(){
18383		
18384		return(typeof Froogaloop != "undefined");
18385	}
18386	
18387	
18388	/**
18389	 * actually put the video
18390	 */
18391	function putVideoActually(divID, videoID, width, height, isAutoplay){
18392		
18393		g_player = null;
18394		g_isPlayerReady = false;
18395		
18396		var url = location.protocol+"//player.vimeo.com/video/"+videoID+"?api=1";
18397		
18398		if(isAutoplay === true)
18399		   url += "&amp;byline=0&amp;autoplay=1&amp;title=0&amp;portrait=0";
18400		
18401		var html = "<iframe src="+url+" width='"+width+"' height='"+height+"' frameborder='0' webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>";
18402		
18403		jQuery("#"+divID).html(html);
18404		
18405		//get the player object
18406		var iframe = jQuery("#"+divID + " iframe")[0];
18407		
18408		g_player = Froogaloop(iframe);
18409
18410		g_player.addEvent('ready', function(){
18411			
18412			if(g_player){
18413				g_isPlayerReady = true;
18414				initEvents();
18415			}
18416			
18417		});
18418		
18419		g_lastCotnainerID = divID;		
18420	}
18421	
18422	/**
18423	 * init events
18424	 */
18425	function initEvents(){
18426		
18427		if(!g_player)
18428			return(false);
18429				
18430		//set "cuechange" event
18431		g_player.addEvent('cuechange', function(){
18432			
18433			if(g_cueChangeAutoplay == true)			
18434				t.play();
18435			
18436		});
18437		
18438		//set "play" event
18439		g_player.addEvent('play', function(){
18440			g_objThis.trigger(t.events.START_PLAYING);
18441		});
18442		
18443		//set "pause event"
18444		g_player.addEvent('pause', function(){
18445			g_objThis.trigger(t.events.STOP_PLAYING);
18446		});
18447		
18448		g_player.addEvent('finish', function(){
18449			g_objThis.trigger(t.events.STOP_PLAYING);
18450			g_objThis.trigger(t.events.VIDEO_ENDED);
18451		});
18452		
18453	}
18454	
18455	
18456	/**
18457	 * do some command
18458	 */
18459	this.doCommand = function(command){
18460		
18461		if(g_player == null)
18462			return(false);
18463		
18464		if(g_isPlayerReady == false)
18465			return(false);
18466		
18467		switch(command){
18468			default:
18469				g_player.api(command);
18470			break;
18471		}
18472		
18473	}
18474	
18475	/**
18476	 * do pause command
18477	 */
18478	this.pause = function(){
18479		t.doCommand("pause");
18480	}
18481	
18482	/**
18483	 * do play command
18484	 */
18485	this.play = function(){
18486		t.doCommand("play");
18487	}
18488	
18489	/**
18490	 * desrtoy the player and empty the div
18491	 */
18492	this.destroy = function(){
18493		
18494		if(g_player){
18495			g_player.api("unload");
18496			g_player = null;
18497			g_isPlayerReady = false;
18498		}
18499		
18500		if(g_lastCotnainerID){
18501			jQuery("#" + g_lastCotnainerID).html("");			
18502		}
18503	
18504	}
18505	
18506	/**
18507	 * put the vimeo video
18508	 */
18509	this.putVideo = function(divID, videoID, width, height, isAutoplay){
18510		
18511		if(isFroogaloopActive()){
18512			putVideoActually(divID, videoID, width, height, isAutoplay);
18513			return(true);
18514		}
18515		
18516		
18517		//if no API present, wait for the API being ready
18518		this.loadAPI();
18519		g_intHandle = setInterval(function(){
18520			
18521			if(isFroogaloopActive()){
18522				putVideoActually(divID, videoID, width, height, isAutoplay);
18523				clearInterval(g_intHandle);
18524			}
18525			
18526		}, 500);
18527		
18528	}
18529	
18530	
18531	/**
18532	 * get if the player is ready
18533	 */
18534	this.isPlayerReady = function(){
18535		
18536		if(g_isPlayerReady && g_player)
18537			return(true);
18538	
18539		return(false);
18540	}	
18541	
18542	/**
18543	 * change the video
18544	 */
18545	this.changeVideo = function(videoID, isAutoplay){
18546		
18547		if(t.isPlayerReady() == false)
18548			return(false);
18549		
18550		g_cueChangeAutoplay = isAutoplay;
18551		
18552		g_player.api("loadVideo", videoID);
18553	}
18554	
18555	
18556	/**
18557	 * get video images
18558	 */
18559	this.getVideoImages = function(videoID, itemIndex, onSuccessFunction){
18560		
18561		var url = location.protocol+"//vimeo.com/api/v2/video/"+videoID+".json";
18562		jQuery.get(url, {}, function(data){
18563			var obj = {};
18564			obj.preview = data[0].thumbnail_large;
18565			obj.thumb = data[0].thumbnail_medium;
18566			onSuccessFunction(itemIndex, obj);
18567		});
18568	}
18569	
18570	
18571}
18572
18573
18574/** -------------- Youtube API class ---------------------*/
18575
18576function UGYoutubeAPI(){
18577	
18578	this.isAPILoaded = false;	
18579	var t = this, g_player = null, g_intHandle, g_isPlayerReady = false;
18580	var g_objThis = jQuery(this), g_prevState = -1, g_lastContainerID;	//unstarted
18581	
18582	var g_options = {
18583			video_youtube_showinfo: true
18584	}
18585	
18586	this.events = {
18587		START_PLAYING: "start_playing",
18588		STOP_PLAYING: "stop_playing",
18589		VIDEO_ENDED: "video_ended"
18590	};
18591	
18592	
18593	/**
18594	 * actually put the video
18595	 */
18596	function putVideoActually(divID, videoID, width, height, isAutoplay){
18597				
18598		if(g_player && g_isPlayerReady){			
18599			g_player.destroy();
18600		}
18601		
18602		var playerVars = {
18603			controls:2,
18604			showinfo:g_options.video_youtube_showinfo, 
18605			rel:0
18606		};
18607		
18608		if(isAutoplay === true)
18609			playerVars.autoplay = 1;
18610			
18611		g_isPlayerReady = false;
18612
18613		g_player = new YT.Player(divID, {
18614		      height: height,
18615		      width: width,
18616		      videoId: videoID,
18617		      playerVars: playerVars,
18618		      events: {
18619		        'onReady': onPlayerReady,
18620		        'onStateChange': onPlayerStateChange
18621		      }
18622		 });
18623		
18624		g_lastContainerID = divID;
18625	}
18626	
18627	
18628	/**
18629	 * check if YT active
18630	 */
18631	function isYTActive(){
18632		
18633		if(typeof YT != "undefined" && typeof YT.Player != "undefined")
18634			return(true);
18635		
18636		return(false);
18637	}
18638	
18639	
18640	/**
18641	 * set options
18642	 */
18643	this.setOptions = function(objOptions){
18644		g_options = jQuery.extend(g_options, objOptions);
18645	}
18646	
18647	
18648	/**
18649	 * put the youtube video
18650	 */
18651	this.putVideo = function(divID, videoID, width, height, isAutoplay){
18652		
18653		if(isYTActive()){
18654			putVideoActually(divID, videoID, width, height, isAutoplay);
18655			return(true);
18656		}
18657		
18658		//if no API present, wait for the API being ready
18659		this.loadAPI();
18660		g_intHandle = setInterval(function(){
18661			
18662			if(isYTActive()){
18663				putVideoActually(divID, videoID, width, height, isAutoplay);
18664				clearInterval(g_intHandle);
18665			}
18666			
18667		}, 500);
18668		
18669	}
18670	
18671	
18672	/**
18673	 * on player ready event
18674	 */
18675	function onPlayerReady(){
18676		g_isPlayerReady = true;
18677	}
18678	
18679	
18680	/**
18681	 * on player state change event
18682	 * trigger events
18683	 */
18684	function onPlayerStateChange(){
18685		
18686		if(typeof g_player.getPlayerState != "function"){
18687			trace("Youtube API error: can't get player state");
18688			return(false);
18689		}
18690		
18691		var state = g_player.getPlayerState();
18692		
18693		switch(state){
18694			case YT.PlayerState.PLAYING:
18695				g_objThis.trigger(t.events.START_PLAYING);
18696			break;
18697			case YT.PlayerState.ENDED:
18698				g_objThis.trigger(t.events.STOP_PLAYING);					
18699				g_objThis.trigger(t.events.VIDEO_ENDED);
18700			break;
18701			default:
18702				if(g_prevState == YT.PlayerState.PLAYING)
18703					g_objThis.trigger(t.events.STOP_PLAYING);					
18704			break;
18705		}
18706		
18707		g_prevState = state;
18708	}
18709	
18710	
18711	/**
18712	 * load youtube API
18713	 */
18714	this.loadAPI = function(){
18715		
18716		if(g_ugYoutubeAPI.isAPILoaded == true)
18717			return(true);
18718		
18719		if(typeof YT != "undefined"){
18720			g_ugYoutubeAPI.isAPILoaded = true;
18721			return(true);
18722		}
18723		
18724		g_ugFunctions.loadJs("https://www.youtube.com/player_api", false);
18725		
18726		g_ugYoutubeAPI.isAPILoaded = true;	
18727		
18728	}
18729	
18730	
18731	/**
18732	 * do some command
18733	 */
18734	this.doCommand = function(command, opt1){
18735		
18736		if(!g_player)
18737			return(true);
18738		
18739		if(g_isPlayerReady == false)
18740			return(false);
18741		
18742		switch(command){
18743			case "play":
18744				if(typeof g_player.playVideo != "function")
18745					return(false);
18746				
18747				g_player.playVideo();
18748			break;
18749			case "pause":
18750				if(typeof g_player.pauseVideo != "function")
18751					return(false);
18752				
18753				g_player.pauseVideo();
18754			break;
18755			case "seek":
18756				if(typeof g_player.seekTo != "function")
18757					return(false);
18758
18759				g_player.seekTo(opt1);
18760			break;
18761			case "stopToBeginning":
18762				var state = g_player.getPlayerState();
18763				
18764				g_player.pauseVideo();
18765				
18766				switch(state){
18767					case YT.PlayerState.PLAYING:
18768					case YT.PlayerState.ENDED:
18769					case YT.PlayerState.PAUSED:
18770						g_player.seekTo(0);
18771					break;
18772				}
18773			break;
18774		}
18775	}
18776	
18777	/**
18778	 * play video
18779	 */
18780	this.play = function(){
18781		t.doCommand("play");		
18782	}
18783	
18784	/**
18785	 * stop the video
18786	 */
18787	this.pause = function(){
18788		t.doCommand("pause");
18789	}
18790	
18791	/**
18792	 * destroy player
18793	 */
18794	this.destroy = function(){
18795		try{
18796			
18797			if(g_player){
18798				g_isPlayerReady = false;	
18799				g_player.clearVideo();
18800				g_player.destroy();
18801			}
18802			
18803		}catch(objError){
18804			
18805			jQuery("#"+g_lastContainerID).html("");
18806			
18807		}
18808		
18809	}
18810	
18811	/**
18812	 * stop the video and seek to start
18813	 */
18814	this.stopToBeginning = function(){
18815		t.doCommand("stopToBeginning");
18816	}
18817	
18818	/**
18819	 * change the video
18820	 */
18821	this.changeVideo = function(videoID, isAutoplay){
18822		
18823		if(t.isPlayerReady() == false)
18824			return(false);
18825		
18826		if(isAutoplay && isAutoplay == true)
18827			g_player.loadVideoById(videoID, 0, "large");
18828		else
18829			g_player.cueVideoById(videoID, 0, "large");
18830	}
18831	
18832	
18833	/**
18834	 * get if the player is ready
18835	 */
18836	this.isPlayerReady = function(){
18837		
18838		if(g_isPlayerReady && g_player)
18839			return(true);
18840	
18841		return(false);
18842	}
18843	
18844		
18845	
18846	/**
18847	 * get preview and thumbs images according the ID
18848	 */
18849	this.getVideoImages = function(videoID){
18850		var obj = {};
18851		obj.preview = "https://i.ytimg.com/vi/"+videoID+"/sddefault.jpg";
18852		obj.thumb = "https://i.ytimg.com/vi/"+videoID+"/default.jpg";
18853		return(obj);
18854	}
18855	
18856	
18857}
18858
18859/** -------------- Video Player Class ---------------------*/
18860
18861
18862function UGVideoPlayer(){
18863	
18864	var t = this, g_galleryID, g_objThis = jQuery(this), g_functions = new UGFunctions();
18865	var g_youtubeAPI = new UGYoutubeAPI(), g_vimeoAPI = new UGVimeoAPI();
18866	var g_html5API = new UGHtml5MediaAPI(), g_soundCloudAPI = new UGSoundCloudAPI(), g_wistiaAPI = new UGWistiaAPI();
18867	var g_objPlayer, g_objYoutube, g_objVimeo, g_objHtml5, g_objButtonClose, g_objSoundCloud, g_objWistia;
18868	var g_activePlayerType = null;
18869	
18870	var g_options = {
18871			video_enable_closebutton: true
18872	};
18873	
18874	this.events = {
18875			SHOW: "video_show",
18876			HIDE: "video_hide",
18877			PLAY_START: "video_play_start",
18878			PLAY_STOP: "video_play_stop",
18879			VIDEO_ENDED: "video_ended"
18880	};
18881	
18882	var g_temp = {
18883			standAloneMode: false,
18884			youtubeInnerID:"",
18885			vimeoPlayerID:"",
18886			html5PlayerID:"",
18887			wistiaPlayerID:"",
18888			soundCloudPlayerID:""
18889	};
18890	
18891	
18892	/**
18893	 * init the object
18894	 */
18895	this.init = function(optOptions, isStandAloneMode, galleryID){
18896		g_galleryID = galleryID;
18897		
18898		if(!g_galleryID)
18899			throw new Error("missing gallery ID for video player, it's a must!");
18900			
18901		g_options =  jQuery.extend(g_options, optOptions);
18902		
18903		g_youtubeAPI.setOptions(g_options);
18904		
18905		if(isStandAloneMode && isStandAloneMode == true)
18906			g_temp.standAloneMode = true;
18907		
18908	}
18909	
18910	
18911	/**
18912	 * set the player html
18913	 */
18914	this.setHtml = function(objParent){
18915		
18916		g_temp.youtubeInnerID = g_galleryID + "_youtube_inner";
18917		g_temp.vimeoPlayerID = g_galleryID + "_videoplayer_vimeo";
18918		g_temp.html5PlayerID = g_galleryID + "_videoplayer_html5";
18919		g_temp.wistiaPlayerID = g_galleryID + "_videoplayer_wistia";
18920		g_temp.soundCloudPlayerID = g_galleryID + "_videoplayer_soundcloud";
18921		
18922		
18923		var html = "<div class='ug-videoplayer' style='display:none'>";
18924		html += "<div class='ug-videoplayer-wrapper ug-videoplayer-youtube' style='display:none'><div id='"+g_temp.youtubeInnerID+"'></div></div>";
18925		html += "<div id='"+g_temp.vimeoPlayerID+"' class='ug-videoplayer-wrapper ug-videoplayer-vimeo' style='display:none'></div>";
18926		html += "<div id='"+g_temp.html5PlayerID+"' class='ug-videoplayer-wrapper ug-videoplayer-html5'></div>";
18927		html += "<div id='"+g_temp.soundCloudPlayerID+"' class='ug-videoplayer-wrapper ug-videoplayer-soundcloud'></div>";
18928		html += "<div id='"+g_temp.wistiaPlayerID+"' class='ug-videoplayer-wrapper ug-videoplayer-wistia'></div>";
18929		
18930		if(g_temp.standAloneMode == false && g_options.video_enable_closebutton == true)
18931			html += "<div class='ug-videoplayer-button-close'></div>";
18932		
18933		html += "</div>";
18934		
18935		objParent.append(html);
18936		
18937		g_objPlayer = objParent.children(".ug-videoplayer");
18938		g_objYoutube = g_objPlayer.children(".ug-videoplayer-youtube");
18939		g_objVimeo = g_objPlayer.children(".ug-videoplayer-vimeo");
18940		g_objHtml5 = g_objPlayer.children(".ug-videoplayer-html5");
18941		g_objSoundCloud = g_objPlayer.children(".ug-videoplayer-soundcloud");
18942		g_objWistia = g_objPlayer.children(".ug-videoplayer-wistia");
18943		
18944		if(g_temp.standAloneMode == false && g_options.video_enable_closebutton == true)
18945			g_objButtonClose = g_objPlayer.children(".ug-videoplayer-button-close")
18946	}
18947
18948	
18949	function __________EVENTS___________(){};	
18950	
18951	/**
18952	 * on close button click event
18953	 */
18954	function onCloseButtonClick(){
18955		t.hide();
18956	}
18957	
18958	/**
18959	 * on some video play start
18960	 */
18961	function onPlayStart(){
18962		
18963		g_objThis.trigger(t.events.PLAY_START);
18964		
18965		if(g_objButtonClose)
18966			g_objButtonClose.hide();
18967	}
18968	
18969	
18970	/**
18971	 * on some video play stop
18972	 */
18973	function onPlayStop(){
18974		
18975		g_objThis.trigger(t.events.PLAY_STOP);
18976		
18977		if(g_objButtonClose)
18978			g_objButtonClose.show();
18979	}
18980	
18981	/**
18982	 * on video ended
18983	 */
18984	function onVideoEnded(){
18985		
18986		g_objThis.trigger(t.events.VIDEO_ENDED);
18987		
18988	}
18989
18990	
18991	/**
18992	 * init events
18993	 */
18994	function initEvents(){
18995		
18996		//close button events
18997		if(g_objButtonClose){
18998			g_functions.setButtonMobileReady(g_objButtonClose);		
18999			g_functions.setButtonOnClick(g_objButtonClose, onCloseButtonClick);					
19000		}
19001		
19002		//youtube events
19003		jQuery(g_youtubeAPI).on(g_youtubeAPI.events.START_PLAYING, onPlayStart);
19004		jQuery(g_youtubeAPI).on(g_youtubeAPI.events.STOP_PLAYING, onPlayStop);
19005		jQuery(g_youtubeAPI).on(g_youtubeAPI.events.VIDEO_ENDED, onVideoEnded);
19006		
19007		//vimeo events
19008		jQuery(g_vimeoAPI).on(g_vimeoAPI.events.START_PLAYING, onPlayStart);
19009		jQuery(g_vimeoAPI).on(g_vimeoAPI.events.STOP_PLAYING, onPlayStop);
19010		jQuery(g_vimeoAPI).on(g_vimeoAPI.events.VIDEO_ENDED, onVideoEnded);
19011		
19012		//html5 video events
19013		jQuery(g_html5API).on(g_html5API.events.START_PLAYING, onPlayStart);
19014		jQuery(g_html5API).on(g_html5API.events.STOP_PLAYING, onPlayStop);
19015		jQuery(g_html5API).on(g_html5API.events.VIDEO_ENDED, onVideoEnded);
19016		
19017		jQuery(g_soundCloudAPI).on(g_soundCloudAPI.events.START_PLAYING, onPlayStart);
19018		jQuery(g_soundCloudAPI).on(g_soundCloudAPI.events.STOP_PLAYING, onPlayStop);
19019		jQuery(g_soundCloudAPI).on(g_soundCloudAPI.events.VIDEO_ENDED, onVideoEnded);
19020		
19021		jQuery(g_wistiaAPI).on(g_wistiaAPI.events.START_PLAYING, onPlayStart);
19022		jQuery(g_wistiaAPI).on(g_wistiaAPI.events.STOP_PLAYING, onPlayStop);
19023		jQuery(g_wistiaAPI).on(g_wistiaAPI.events.VIDEO_ENDED, onVideoEnded);
19024		
19025	}
19026	
19027	
19028	/**
19029	 * destroy the video player events
19030	 */
19031	this.destroy = function(){
19032		
19033		if(g_objButtonClose){
19034			g_objButtonClose.off("click");
19035			g_objButtonClose.off("touchend");
19036		}
19037		
19038		//youtube events
19039		jQuery(g_youtubeAPI).off(g_youtubeAPI.events.START_PLAYING);
19040		jQuery(g_youtubeAPI).off(g_youtubeAPI.events.STOP_PLAYING);
19041		
19042		//vimeo events
19043		jQuery(g_vimeoAPI).off(g_vimeoAPI.events.START_PLAYING);
19044		jQuery(g_vimeoAPI).off(g_vimeoAPI.events.STOP_PLAYING);
19045		
19046		//html5 video events
19047		jQuery(g_html5API).off(g_html5API.events.START_PLAYING);
19048		jQuery(g_html5API).off(g_html5API.events.STOP_PLAYING);
19049		
19050		jQuery(g_soundCloudAPI).off(g_soundCloudAPI.events.START_PLAYING, onPlayStart);
19051		jQuery(g_soundCloudAPI).off(g_soundCloudAPI.events.STOP_PLAYING, onPlayStop);
19052		
19053		jQuery(g_wistiaAPI).off(g_wistiaAPI.events.START_PLAYING, onPlayStart);
19054		jQuery(g_wistiaAPI).off(g_wistiaAPI.events.STOP_PLAYING, onPlayStop);
19055		
19056		g_activePlayerType = null;
19057	}
19058	
19059	
19060	/**
19061	 * init events
19062	 */
19063	this.initEvents = function(){
19064		
19065		initEvents();
19066	}
19067	
19068	
19069	/**
19070	 * set element size and position the button
19071	 */
19072	this.setSize = function(width, height){
19073		
19074		g_functions.setElementSize(g_objPlayer, width, height);
19075		
19076		if(g_objButtonClose)
19077			g_functions.placeElement(g_objButtonClose, "right", "top");
19078		
19079	}
19080	
19081	
19082	/**
19083	 * set video player position
19084	 */
19085	this.setPosition = function(left, top){
19086		g_functions.placeElement(g_objPlayer, left, top);
19087	}
19088	
19089	/**
19090	 * get video player object for placing
19091	 */
19092	this.getObject = function(){
19093		return(g_objPlayer);
19094	}
19095	
19096	
19097	/**
19098	 * show the player
19099	 */
19100	this.show = function(){		
19101		
19102		if(t.isVisible() == true)
19103			return(true);
19104		
19105		g_objPlayer.show();
19106		
19107		g_objPlayer.fadeTo(0,1);
19108		
19109		if(g_objButtonClose)
19110			g_objButtonClose.show();
19111				
19112		g_objThis.trigger(t.events.SHOW);
19113	}
19114		
19115	
19116	/**
19117	 * hide the player
19118	 */
19119	this.hide = function(){
19120		
19121		if(t.isVisible() == false)
19122			return(true);
19123		
19124		//pause all players
19125		stopAndHidePlayers();
19126		
19127		g_activePlayerType = null;
19128		
19129		g_objPlayer.hide();
19130		
19131		g_objThis.trigger(t.events.HIDE);
19132	}
19133	
19134	
19135	/**
19136	 * get active player
19137	 */
19138	this.getActiveAPI = function(){
19139		
19140		switch(g_activePlayerType){
19141			case "youtube":
19142				return g_youtubeAPI;
19143			break;
19144			case "vimeo":
19145				return g_vimeoAPI;
19146			break;
19147			case "wistia":
19148				return g_wistiaAPI;
19149			break;
19150			case "soundcloud":
19151				return g_soundCloudAPI;
19152			break;
19153			case "html5":
19154				return g_html5API;
19155			break;
19156			default:
19157				return null;
19158			break;
19159		}
19160	}
19161	
19162	
19163	/**
19164	 * pause active player if playing
19165	 */
19166	this.pause = function(){
19167		
19168		var activeAPI = t.getActiveAPI();
19169		if(activeAPI == null)
19170			return(false);
19171		
19172		if(typeof activeAPI.pause == "function")
19173			activeAPI.pause();
19174			
19175	}
19176	
19177	
19178	/**
19179	 * return if the player is visible
19180	 */
19181	this.isVisible = function(){
19182		
19183		return g_objPlayer.is(":visible");
19184	}
19185	
19186	
19187	/**
19188	 * stop and hide other elements except some
19189	 */
19190	function stopAndHidePlayers(except){
19191		
19192		var arrPlayers = ["youtube", "vimeo", "html5", "soundcloud", "wistia"];
19193		for(var index in arrPlayers){
19194			var player = arrPlayers[index];
19195			if(player == except)
19196				continue;
19197			switch(player){
19198				case "youtube":		
19199					g_youtubeAPI.pause();
19200					g_youtubeAPI.destroy();	
19201					g_objYoutube.hide();
19202				break;
19203				case "vimeo":
19204					g_vimeoAPI.pause();
19205					g_vimeoAPI.destroy();
19206					g_objVimeo.hide();
19207				break;
19208				case "html5":
19209					g_html5API.pause();
19210					g_objHtml5.hide();
19211				break;
19212				case "soundcloud":
19213					g_soundCloudAPI.pause();
19214					g_soundCloudAPI.destroy();
19215					g_objSoundCloud.hide();
19216				break;
19217				case "wistia":
19218					g_wistiaAPI.pause();
19219					g_objWistia.hide();
19220				break;
19221			}
19222		}
19223		
19224	}
19225	
19226	
19227	/**
19228	 * play youtube inside the video, isAutoplay - true by default
19229	 */
19230	this.playYoutube = function(videoID, isAutoplay){
19231				
19232		if(typeof isAutoplay == "undefined")
19233			var isAutoplay = true;
19234		
19235		stopAndHidePlayers("youtube");
19236		
19237		g_objYoutube.show();
19238		
19239		var objYoutubeInner = g_objYoutube.children("#"+g_temp.youtubeInnerID);
19240		if(objYoutubeInner.length == 0)
19241			g_objYoutube.append("<div id='"+g_temp.youtubeInnerID+"'></div>");
19242			
19243		
19244		if(g_youtubeAPI.isPlayerReady() == true && g_temp.standAloneMode == true)
19245			g_youtubeAPI.changeVideo(videoID, isAutoplay);
19246		else{
19247			g_youtubeAPI.putVideo(g_temp.youtubeInnerID, videoID, "100%", "100%", isAutoplay);
19248		}
19249		
19250		g_activePlayerType = "youtube";
19251	}
19252	
19253	
19254	/**
19255	 * play vimeo
19256	 */
19257	this.playVimeo = function(videoID, isAutoplay){
19258		
19259		if(typeof isAutoplay == "undefined")
19260			var isAutoplay = true;
19261		
19262		stopAndHidePlayers("vimeo");
19263		
19264		g_objVimeo.show();
19265
19266		g_vimeoAPI.putVideo(g_temp.vimeoPlayerID, videoID, "100%", "100%", isAutoplay);
19267		
19268		/*
19269		if(g_vimeoAPI.isPlayerReady() && g_temp.standAloneMode == true){
19270			g_vimeoAPI.changeVideo(videoID, isAutoplay);
19271		}
19272		else
19273			g_vimeoAPI.putVideo(g_temp.vimeoPlayerID, videoID, "100%", "100%", isAutoplay);
19274		 */
19275		
19276		g_activePlayerType = "vimeo";
19277
19278	}
19279	
19280	
19281	/**
19282	 * play html5 video
19283	 */
19284	this.playHtml5Video = function(ogv, webm, mp4, posterImage, isAutoplay){
19285		
19286		if(typeof isAutoplay == "undefined")
19287			var isAutoplay = true;
19288				
19289		stopAndHidePlayers("html5");
19290		
19291		g_objHtml5.show();
19292		
19293		//trace(posterImage);
19294		
19295		var data = {
19296				ogv: ogv, 
19297				webm: webm, 
19298				mp4: mp4, 
19299				posterImage: posterImage 
19300			};
19301		
19302		g_html5API.putVideo(g_temp.html5PlayerID, data, "100%", "100%", isAutoplay);
19303		
19304		g_activePlayerType = "html5";
19305
19306	}
19307
19308	/**
19309	 * play sound cloud
19310	 */
19311	this.playSoundCloud = function(trackID, isAutoplay){
19312		
19313		if(typeof isAutoplay == "undefined")
19314			var isAutoplay = true;
19315		
19316		stopAndHidePlayers("soundcloud");
19317		
19318		g_objSoundCloud.show();
19319		
19320		g_soundCloudAPI.putSound(g_temp.soundCloudPlayerID, trackID, "100%", "100%", isAutoplay);
19321
19322		g_activePlayerType = "soundcloud";
19323	
19324	}
19325	
19326	
19327	/**
19328	 * play sound cloud
19329	 */
19330	this.playWistia = function(videoID, isAutoplay){
19331		
19332		if(typeof isAutoplay == "undefined")
19333			var isAutoplay = true;
19334		
19335		stopAndHidePlayers("wistia");
19336		
19337		g_objWistia.show();
19338		
19339		g_wistiaAPI.putVideo(g_temp.wistiaPlayerID, videoID, "100%", "100%", isAutoplay);
19340	
19341		g_activePlayerType = "wistia";
19342
19343	}
19344	
19345}
19346
19347
19348var g_ugYoutubeAPI = new UGYoutubeAPI();
19349var g_ugVimeoAPI = new UGVimeoAPI();
19350var g_ugHtml5MediaAPI = new UGHtml5MediaAPI();
19351var g_ugSoundCloudAPI = new UGSoundCloudAPI();
19352var g_ugWistiaAPI = new UGWistiaAPI();
19353
19354
19355	/**
19356	 * prototype gallery funciton
19357	 */
19358	jQuery.fn.unitegallery = function(options){
19359		var element = jQuery(this);
19360		var galleryID = "#" + element.attr("id");
19361		
19362		if(!options)
19363			var options = {};
19364				
19365		var objGallery = new UniteGalleryMain();
19366		objGallery.run(galleryID, options);
19367		
19368		var api = new UG_API(objGallery);
19369		
19370		return(api);
19371	}
19372
19373	
19374	/**
19375	 * check for min jquery version
19376	 */
19377	function ugCheckForMinJQueryVersion(){
19378		
19379		var isMinJQuery = g_ugFunctions.checkMinJqueryVersion("1.8.0");
19380		
19381		if(isMinJQuery == false)
19382			throw new Error("The gallery can run from jquery 1.8 You have jQuery "+jQuery.fn.jquery+" Please update your jQuery library.");
19383	}
19384	
19385	
19386	/**
19387	 * check for errors function
19388	 */
19389	function ugCheckForErrors(galleryID, type){
19390
19391		/**
19392		 * check for jquery presents
19393		 */
19394		function checkForJqueryPresents(){
19395			if(typeof jQuery == "undefined")
19396				throw new Error("jQuery library not included");
19397		}
19398		
19399		/**
19400		 * check for double jquery error
19401		 */
19402		function checkForDoubleJQuery(){
19403
19404			if(typeof jQuery.fn.unitegallery == "function")
19405				return(true);
19406			
19407			var errorMessage = "You have some jquery.js library include that comes after the gallery files js include.";
19408			errorMessage += "<br> This include eliminates the gallery libraries, and make it not work.";
19409			
19410			if(type == "cms"){
19411				errorMessage += "<br><br> To fix it you can:<br>&nbsp;&nbsp;&nbsp; 1. In the Gallery Settings -> Troubleshooting set option:  <strong><b>Put JS Includes To Body</b></strong> option to true.";
19412				errorMessage += "<br>&nbsp;&nbsp;&nbsp; 2. Find the double jquery.js include and remove it.";
19413			}else{
19414				errorMessage += "<br><br> Please find and remove this jquery.js include and the gallery will work. <br> * There should be only one jquery.js include before all other js includes in the page.";			
19415			}
19416			
19417			
19418			throw new Error(errorMessage);
19419		}
19420		
19421		try{
19422			if(type == "jquery"){
19423				checkForJqueryPresents();
19424				ugCheckForMinJQueryVersion();
19425			}else{
19426				ugCheckForMinJQueryVersion();
19427				checkForDoubleJQuery();
19428			}
19429			
19430		}catch(objError){
19431			
19432			var message = objError.message;
19433			message = "Unite Gallery Error: "+ message;
19434			message = "<div style='font-size:16px;color:#BC0C06;max-width:900px;border:1px solid red;padding:10px;'>" + message + "</div>"
19435			
19436			if(type == "jquery"){
19437				var objGallery = document.getElementById(galleryID);
19438				objGallery.innerHTML = message;
19439				objGallery.style.display = "block";
19440			}
19441			else
19442				jQuery(galleryID).show().html(message);
19443			
19444			return(false);
19445		}
19446		
19447		return(true);
19448	}
19449
19450	
19451function UniteGalleryMain(){
19452	
19453	var t = this;
19454	var g_galleryID;
19455	var g_objGallery = jQuery(t), g_objWrapper, g_objParent;
19456	var g_objThumbs, g_objSlider, g_functions = new UGFunctions(), g_objTabs, g_objLoadMore;
19457	var g_arrItems = [], g_numItems, g_selectedItem = null, g_selectedItemIndex = -1;
19458	var g_objTheme, g_objCache = {};
19459	
19460	this.events = {
19461			ITEM_CHANGE: "item_change",
19462			SIZE_CHANGE: "size_change",
19463			ENTER_FULLSCREEN: "enter_fullscreen",
19464			EXIT_FULLSCREEN: "exit_fullscreen",
19465			START_PLAY: "start_play",
19466			STOP_PLAY: "stop_play",
19467			PAUSE_PLAYING: "pause_playing",
19468			CONTINUE_PLAYING: "continue_playing",
19469			SLIDER_ACTION_START: "slider_action_start",
19470			SLIDER_ACTION_END: "slider_action_end",
19471			ITEM_IMAGE_UPDATED: "item_image_updated",
19472			GALLERY_KEYPRESS: "gallery_keypress",
19473			GALLERY_BEFORE_REQUEST_ITEMS: "gallery_before_request_items",	//before ajax load items
19474			OPEN_LIGHTBOX:"open_lightbox",
19475			CLOSE_LIGHTBOX:"close_lightbox"			
19476	};
19477	
19478	
19479	//set the default gallery options
19480	var g_options = {				
19481			gallery_width:900,							//gallery width		
19482			gallery_height:500,							//gallery height
19483			
19484			gallery_min_width: 150,						//gallery minimal width when resizing
19485			gallery_min_height: 100,					//gallery minimal height when resizing
19486			
19487			gallery_theme:"default",					//default,compact,grid,slider - select your desired theme from the list of themes.
19488			gallery_skin:"default",						//default, alexis etc... - the global skin of the gallery. Will change all gallery items by default.
19489			
19490			gallery_images_preload_type:"minimal",		//all , minimal , visible - preload type of the images.
19491														//minimal - only image nabours will be loaded each time.
19492														//visible - visible thumbs images will be loaded each time.
19493														//all - load all the images first time.
19494			
19495			gallery_autoplay:false,						//true / false - begin slideshow autoplay on start
19496			gallery_play_interval: 3000,				//play interval of the slideshow
19497			gallery_pause_on_mouseover: true,			//true,false - pause on mouseover when playing slideshow true/false
19498			
19499			gallery_mousewheel_role:"zoom",				//none, zoom, advance
19500			gallery_control_keyboard: true,				//true,false - enable / disble keyboard controls
19501			gallery_carousel:true,						//true,false - next button on last image goes to first image.
19502			
19503			gallery_preserve_ratio: true,				//true, false - preserver ratio when on window resize
19504			gallery_background_color: "",				//set custom background color. If not set it will be taken from css.
19505			gallery_debug_errors:false,					//show error message when there is some error on the gallery area.
19506			gallery_shuffle:false,						//randomise position of items at start.
19507			gallery_urlajax:null,						//ajax url for requesting new items etc.
19508			gallery_enable_tabs: false,					//enable/disable category tabs
19509			gallery_enable_loadmore: false,				//enable / disable loadmore button
19510			gallery_enable_cache: true,					//enable caching items
19511			gallery_initial_catid: ""					//initial category id (for caching)
19512	};
19513	
19514	//gallery_control_thumbs_mousewheel
19515	
19516	var g_temp = {					//temp variables
19517		objCustomOptions:{},
19518		isAllItemsPreloaded:false,	//flag that tells that all items started preloading
19519		isFreestyleMode:false,		//no special html additions
19520		lastWidth:0,
19521		lastHeigh:0,
19522		handleResize: null,
19523		isInited: false,
19524		isPlayMode: false,
19525		isPlayModePaused: false,
19526		playTimePassed: 0,
19527		playTimeLastStep: 0,
19528		playHandle: "",
19529		playStepInterval: 33,
19530		objProgress: null,
19531		isFakeFullscreen: false,
19532		thumbsType:null,
19533		isYoutubePresent:false,			//flag if present youtube items
19534		isVimeoPresent:false,			//flag if present vimeo items
19535		isHtml5VideoPresent:false,		//flag if present html5 video items
19536		isSoundCloudPresent:false,		//flag if present soundcloud items
19537		isWistiaPresent: false,			//flag if some wistia movie present
19538		resizeDelay: 100,
19539		isRunFirstTime: true,
19540		originalOptions: {},
19541		funcCustomHeight: null			//custom height function, set by the theme if needed
19542	};
19543	
19544	
19545	
19546	function __________INIT_GALLERY_______(){};
19547	
19548	/**
19549	 * get theme function from theme name
19550	 */
19551	function getThemeFunction(themeName){
19552		 var themeFunction = themeName;
19553		if(themeFunction.indexOf("UGTheme_") == -1)
19554			 themeFunction = "UGTheme_" + themeFunction;
19555		
19556		return(themeFunction);
19557	}
19558
19559	/**
19560	 * init the theme
19561	 */
19562	function initTheme(objCustomOptions){
19563		 
19564		//set theme function:
19565		 if(objCustomOptions.hasOwnProperty("gallery_theme"))
19566			 g_options.gallery_theme = objCustomOptions.gallery_theme;
19567		 else{
19568			 var defaultTheme = g_options.gallery_theme;
19569			 if(g_ugFunctions.isThemeRegistered(defaultTheme) == false)
19570				 g_options.gallery_theme = g_ugFunctions.getFirstRegisteredTheme();
19571		 }
19572		 
19573		 var themeFunction = getThemeFunction(g_options.gallery_theme);
19574		 
19575		 try{
19576			 g_options.gallery_theme = eval(themeFunction);
19577		 }catch(e){
19578			 //check registered themes
19579		 };
19580		 
19581		 g_options.gallery_theme = eval(themeFunction);
19582		 
19583		 //init the theme
19584		 g_objTheme = new g_options.gallery_theme();
19585		 g_objTheme.init(t, objCustomOptions);
19586	}
19587	
19588	
19589	/**
19590	 * reset all the options for the second time run
19591	 */
19592	function resetOptions(){
19593	   	 
19594		 g_options = jQuery.extend({}, g_temp.originalOptions);
19595		 
19596		 g_selectedItemIndex = -1;
19597		 g_selectedItem = null;
19598		 g_objSlider = undefined;
19599		 g_objThumbs = undefined;
19600		 g_objSlider = undefined; 
19601	}
19602	
19603	
19604	/**
19605	 * check for some errors and fire error if needed
19606	 */
19607	function checkForStartupErrors(){
19608		
19609		//protection agains old jquery version
19610		try{
19611			ugCheckForMinJQueryVersion();
19612		}catch(e){
19613			throwErrorShowMessage(e.message);
19614		}
19615		
19616		//protection against some jquery ui function change
19617	     if(typeof g_objWrapper.outerWidth() == "object")
19618	    	 throwErrorShowMessage("You have some buggy script. most chances jquery-ui.js that destroy jquery outerWidth, outerHeight functions. The gallery can't run. Please update jquery-ui.js to latest version.");
19619	     
19620	     //check for late jquery include
19621	     setTimeout(function(){ugCheckForErrors(g_galleryID, "cms")} , 5000);
19622	     
19623	}
19624	
19625	
19626	
19627	/**
19628	 *  the gallery
19629	 */
19630	function runGallery(galleryID, objCustomOptions, htmlItems, cacheID){
19631			
19632			var isCustomOptions = (typeof objCustomOptions == "object");
19633			
19634			if(isCustomOptions)
19635		      g_temp.objCustomOptions = objCustomOptions;
19636			 			 
19637		     if(g_temp.isRunFirstTime == true){
19638				
19639		    	 g_galleryID = galleryID;
19640				 g_objWrapper = jQuery(g_galleryID);
19641				 if(g_objWrapper.length == 0){
19642					 trace("div with id: "+g_galleryID+" not found");
19643					 return(false);
19644				 }
19645
19646				 g_objParent = g_objWrapper.parent();
19647				 
19648				 checkForStartupErrors();
19649				 
19650				 g_temp.originalOptions = jQuery.extend({}, g_options);
19651				 
19652				 //merge options
19653				 if(isCustomOptions)
19654					 g_options = jQuery.extend(g_options, objCustomOptions);
19655				 
19656				 //cache items
19657				 if(g_options.gallery_enable_cache == true && g_options.gallery_initial_catid)
19658					 cacheItems(g_options.gallery_initial_catid);
19659				
19660				 //set size class
19661				 t.setSizeClass();
19662				 
19663				 //fill arrItems
19664				 var objItems = g_objWrapper.children();
19665				 
19666				 fillItemsArray(objItems);
19667				 loadAPIs();
19668				 
19669				 //hide images:
19670				 g_objWrapper.find("img").fadeTo(0,0).hide();
19671				 g_objWrapper.show();
19672		
19673				 clearInitData();
19674		    	 
19675		     }else{		//reset options - not first time run
19676		    	 
19677		    	 t.destroy();
19678		    	 
19679		    	 resetOptions();
19680
19681		    	 g_options = jQuery.extend(g_options, g_temp.objCustomOptions);
19682	    		 
19683		    	 if(htmlItems){
19684		    		 
19685		    		 //cache items
19686		    		 if(cacheID && g_options.gallery_enable_cache == true)
19687		    			 cacheItems(cacheID, htmlItems);
19688		    		 
19689		    		 if(htmlItems == "noitems"){
19690		    			 showErrorMessage("No items in this category","");
19691		    			 return(false);
19692			    	 }
19693		    		 
19694		    		 g_objWrapper.html(htmlItems);
19695		    		 
19696		    		 var objItems = g_objWrapper.children();
19697		    		 fillItemsArray(objItems);
19698					 
19699		    		 loadAPIs();
19700					 
19701					 g_objWrapper.children().fadeTo(0,0).hide();
19702					 
19703					 g_objWrapper.show();
19704					 clearInitData();
19705		    	 }
19706		     
19707		     }
19708		     
19709			 //init tabs
19710			 if(g_temp.isRunFirstTime == true && g_options.gallery_enable_tabs == true){
19711				 g_objTabs = new UGTabs();
19712				 g_objTabs.init(t, g_options);
19713			 }
19714			 
19715			 //init loadmore button
19716			 if(g_temp.isRunFirstTime == true && g_options.gallery_enable_loadmore == true){
19717				 g_objLoadMore = new UGLoadMore();
19718				 g_objLoadMore.init(t, g_options);
19719			 }
19720			 
19721			 //modify and verify the params
19722			 if(isCustomOptions)
19723				 modifyInitParams(g_temp.objCustomOptions);
19724			 			 
19725			 validateParams();
19726			 
19727			 //shuffle items
19728			 if(g_options.gallery_shuffle == true)
19729				 t.shuffleItems();
19730			 
19731			 //init the theme
19732			 initTheme(g_temp.objCustomOptions);
19733			 			 				 
19734			 //set gallery html elements
19735			 setGalleryHtml();
19736
19737			 //set html properties to all elements
19738			 setHtmlObjectsProperties();
19739			 
19740			 var galleryWidth = g_objWrapper.width();
19741			 
19742			 if(galleryWidth == 0){
19743				 g_functions.waitForWidth(g_objWrapper, runGalleryActually);
19744			 }else
19745				 runGalleryActually();
19746			 
19747	}
19748	
19749	
19750	/**
19751	 * actually run the gallery
19752	 */
19753	function runGalleryActually(){
19754		 
19755		t.setSizeClass();
19756		
19757		if(g_temp.isFreestyleMode == false){
19758			 	
19759			 if(g_options.gallery_preserve_ratio == true)
19760				 setHeightByOriginalRatio();
19761		 }
19762		 
19763		 g_objTheme.run();
19764		 
19765		 if(g_objTabs && g_temp.isRunFirstTime)
19766			 g_objTabs.run();
19767		 
19768		 
19769		 preloadBigImages();
19770		 
19771		 initEvents();
19772		 
19773		 //select first item
19774		 if(g_numItems > 0) 
19775			 t.selectItem(0);
19776		 
19777		 
19778		 //set autoplay
19779		 if(g_options.gallery_autoplay == true)
19780			 t.startPlayMode();
19781		 
19782		 g_temp.isRunFirstTime = false;
19783		
19784	}
19785	
19786	
19787	/**
19788	 * 
19789	 * show error message
19790	 */
19791	function showErrorMessage(message, prefix){
19792
19793		if(typeof prefix == "undefined")
19794			var prefix = "<b>Unite Gallery Error: </b>";			
19795		else
19796			prefix = "<b>"+prefix+": </b>";
19797		
19798		message = prefix + message;
19799		
19800		var html = "<div class='ug-error-message-wrapper'><div class='ug-error-message'>" + message + "</div></div>";
19801		
19802		g_objWrapper.children().remove();
19803		
19804		g_objWrapper.html(html);
19805		g_objWrapper.show();		
19806	}
19807	
19808	/**
19809	 * show error message and throw error
19810	 */
19811	function throwErrorShowMessage(message){
19812		showErrorMessage(message);
19813		throw new Error(message);
19814	}
19815	
19816	
19817	/**
19818	 * 
19819	 * @param objParams
19820	 */
19821	 function modifyInitParams(){
19822		 
19823		 //set default for preloading
19824		 if(!g_options.gallery_images_preload_type)
19825			 g_options.gallery_images_preload_type = "minimal";
19826		 
19827		 //normalize gallery min height and width
19828		 if(g_options.gallery_min_height == undefined || g_options.gallery_height < g_options.gallery_min_height){
19829			 g_options.gallery_min_height = 0;
19830		 }
19831		 
19832		 if(g_options.gallery_min_width == undefined || g_options.gallery_width < g_options.gallery_min_width){
19833			 g_options.gallery_min_width = 0;
19834		 }
19835		 
19836	 }
19837
19838	
19839	/**
19840	 * validate the init parameters
19841	 */
19842	 function validateParams(){
19843		 
19844		 //validate theme:
19845		 if(!g_options.gallery_theme)
19846			 throw new Error("The gallery can't run without theme");
19847		 		 
19848		 //if(typeof g_options.theme != "function")
19849			 //throw new Error("Wrong theme function: " + g_options.theme.toString());
19850		 
19851		 //validate height and width
19852		 if(jQuery.isNumeric(g_options.gallery_height) && g_options.gallery_height < g_options.gallery_min_height)
19853			 throw new Error("The <b>gallery_height</b> option must be bigger then <b>gallery_min_height option</b>");
19854		 
19855		 if(g_options.gallery_width < g_options.gallery_min_width)
19856			 throw new Error("The <b>gallery_width</b> option must be bigger then <b>gallery_min_width option</b>");
19857		 
19858		 
19859	 }
19860	 
19861	 
19862	 /**
19863	 * set gallery html
19864	 */
19865	function setGalleryHtml(){
19866		
19867		 //add classes and divs
19868		 g_objWrapper.addClass("ug-gallery-wrapper");
19869		 
19870		 g_objWrapper.append("<div class='ug-overlay-disabled' style='display:none'></div>");
19871		 
19872		 t.setSizeClass();
19873	}
19874	
19875	
19876	/**
19877	 * if the thumbs panel don't exists, delete initial images from dom
19878	 */
19879	function clearInitData(){
19880		
19881		var objItems = g_objWrapper.children().remove();
19882	}
19883	
19884	
19885	/**
19886	 * store last gallery size
19887	 */
19888	function storeLastSize(){
19889		var objSize = t.getSize();
19890		
19891		g_temp.lastWidth = objSize.width;
19892		g_temp.lastHeight = objSize.height;
19893	}
19894	
19895	
19896	/**
19897	 * set gallery height by original ratio
19898	 */
19899	function setHeightByOriginalRatio(){
19900		
19901		var objSize = t.getSize();
19902				
19903		var ratio = objSize.width / objSize.height;
19904		
19905		if(ratio != objSize.orig_ratio){
19906			
19907			var newHeight = objSize.width / objSize.orig_ratio;
19908			newHeight = Math.round(newHeight);
19909			
19910			if(newHeight < g_options.gallery_min_height)
19911				newHeight = g_options.gallery_min_height;
19912			
19913			g_objWrapper.height(newHeight);
19914		}
19915	
19916	}
19917
19918	
19919	/**
19920	 * set properties of the html objects
19921	 */
19922	function setHtmlObjectsProperties(){
19923		   
19924			var optionWidth = g_functions.getCssSizeParam(g_options.gallery_width);
19925			
19926		   //set size		
19927		   var objCss = {
19928				    //"width":optionWidth,		//make it work within tabs
19929				    "max-width":optionWidth,
19930					"min-width":g_functions.getCssSizeParam(g_options.gallery_min_width)
19931			};
19932		   
19933		   if(g_temp.isFreestyleMode == false){
19934			   
19935			   var galleryHeight = g_functions.getCssSizeParam(g_options.gallery_height);
19936			   objCss["height"] = galleryHeight;
19937		   
19938		   }else{
19939			   objCss["overflow"] = "visible";			   
19940		   }
19941		   
19942		   //set background color
19943		   if(g_options.gallery_background_color)
19944			   objCss["background-color"] = g_options.gallery_background_color;
19945		   
19946		   
19947		   g_objWrapper.css(objCss);
19948		   
19949	}
19950
19951	
19952	/**
19953	 * fill item by html child
19954	 */
19955	function fillItemByChild(objChild){
19956		
19957		var isMobile = t.isMobileMode();
19958		
19959		 var tagname = objChild.prop("tagName").toLowerCase();
19960		 
19961		 //handle link wrapper
19962		 var itemLink = "";
19963		 if(tagname == "a"){
19964			 itemLink = objChild.attr("href");
19965			 objChild = objChild.children();
19966			 var tagname = objChild.prop("tagName").toLowerCase();				 
19967		 }
19968		 
19969		 var itemType = objChild.data("type");
19970		 if(itemType == undefined)
19971			 itemType = "image";
19972		 
19973		 var objItem = {};
19974		 objItem.type = itemType;
19975		 
19976		 if(tagname == "img"){
19977			 
19978			 //protection agains lasy load
19979			 var lasyLoadSrc = objChild.data("lazyload-src");
19980			 if(lasyLoadSrc && lasyLoadSrc != ""){
19981				 objChild.attr("src", lasyLoadSrc);
19982				 jQuery.removeData(objChild, "lazyload-src");
19983			 }
19984			 
19985			 //src is thumb
19986			 var urlImage = objChild.data("image");
19987			 var urlThumb = objChild.data("thumb");
19988			 
19989			 if(typeof(urlImage) == "undefined")
19990				 urlImage = null;
19991			 
19992			 if(typeof(urlThumb) == "undefined")
19993				 urlThumb = null;
19994			 
19995			 var imageSrc = objChild.attr("src");
19996			 
19997			 if(!urlImage)
19998				 urlImage = imageSrc;
19999				 
20000			 if(!urlThumb)
20001				 urlThumb = imageSrc;
20002			 
20003			 if(!urlThumb)
20004				 urlThumb = urlImage;
20005			 
20006			 if(!urlImage)
20007				 urlImage = urlThumb;
20008			 
20009			 objItem.urlThumb = urlThumb;
20010			 objItem.urlImage = urlImage;
20011			 				 
20012			 objItem.title = objChild.attr("alt");
20013			 
20014			 //always set thumb image to object
20015			 objItem.objThumbImage = objChild;
20016			 
20017			 objItem.objThumbImage.attr("src", objItem.urlThumb);
20018			 
20019		 }else{
20020			 
20021			 if(itemType == "image"){
20022				 trace("Problematic gallery item found:");
20023				 trace(objChild);
20024				 trace("Please look for some third party js script that could add this item to the gallery");
20025				 throw new Error("The item should not be image type");
20026			 }
20027			 
20028			 objItem.urlThumb = objChild.data("thumb");
20029			 objItem.title = objChild.data("title");
20030			 objItem.objThumbImage = null;
20031			 objItem.urlImage = objChild.data("image");
20032		 }
20033		 
20034		 //trace(isMobile);
20035		 
20036		 //check mobile version images
20037		 if(isMobile == true){
20038			 
20039			 var urlThumbMobile = objChild.data("thumb-mobile");
20040			 if(typeof urlThumbMobile != "undefined" && urlThumbMobile != ""){
20041				 objItem.urlThumb = urlThumbMobile;
20042 			 	 
20043				 if(tagname == "img")
20044 					 objChild.attr("src",objItem.urlThumb);
20045			 }
20046			 
20047			 var urlImageMobile = objChild.data("image-mobile");
20048			 if(typeof urlImageMobile != "undefined" && urlImageMobile != "")
20049				 objItem.urlImage = urlImageMobile;
20050		 }
20051		 
20052		 objItem.link = itemLink;
20053		 
20054		 //get description:
20055		 objItem.description = objChild.attr("title");
20056		 if(!objItem.description)				 
20057			 objItem.description = objChild.data("description");
20058		 
20059		 if(!objItem.description)
20060			 objItem.description = "";
20061		 
20062		 objItem.isNewAdded = false;		//fill outside
20063		 objItem.isLoaded = false;
20064		 objItem.isThumbImageLoaded = false;	//if the image loaded or error load
20065		 objItem.objPreloadImage = null;
20066		 objItem.isBigImageLoadStarted = false;
20067		 objItem.isBigImageLoaded = false;
20068		 objItem.isBigImageLoadError = false;			 
20069		 objItem.imageWidth = 0;
20070		 objItem.imageHeight = 0;
20071		 
20072		 //set thumb size
20073		 objItem.thumbWidth = 0;
20074		 objItem.thumbHeight = 0;
20075		 objItem.thumbRatioByWidth = 0;
20076		 objItem.thumbRatioByHeight = 0;
20077		 
20078		 var dataWidth = objChild.data("width");
20079		 var dataHeight = objChild.data("height");
20080		 if(dataWidth && typeof dataWidth == "number" && dataHeight && typeof dataHeight == "number"){
20081			 objItem.thumbWidth = dataWidth;
20082			 objItem.thumbHeight = dataHeight;
20083			 objItem.thumbRatioByWidth = dataWidth / dataHeight;
20084			 objItem.thumbRatioByHeight = dataHeight / dataWidth;
20085		 }
20086		 
20087		 objItem.addHtml = null;
20088		 
20089		 var isImageMissing = (objItem.urlImage == undefined || objItem.urlImage == "");
20090		 var isThumbMissing = (objItem.urlThumb == undefined || objItem.urlThumb == "");
20091		 
20092		 switch(objItem.type){
20093		 	case "youtube":			 		
20094				 objItem.videoid = objChild.data("videoid");
20095		 		 
20096				 if(isImageMissing || isThumbMissing){
20097					 
20098					 var objImages = g_ugYoutubeAPI.getVideoImages(objItem.videoid);
20099				 		
20100			 		 //set preview image
20101			 		 if(isImageMissing)
20102			 			objItem.urlImage = objImages.preview;
20103			 		
20104			 		 //set thumb image
20105			 		 if(isThumbMissing){
20106			 			 	objItem.urlThumb = objImages.thumb;
20107			 				
20108			 			 	 if(tagname == "img")
20109			 					 objChild.attr("src",objItem.urlThumb);
20110			 		 }
20111					 
20112				 }
20113				 
20114				 g_temp.isYoutubePresent = true;
20115			break;
20116		 	case "vimeo":
20117		 		
20118				objItem.videoid = objChild.data("videoid");
20119									
20120				g_temp.isVimeoPresent = true;
20121		 	break;
20122		 	case "html5video":
20123		 		objItem.videoogv = objChild.data("videoogv");
20124		 		objItem.videowebm = objChild.data("videowebm");
20125		 		objItem.videomp4 = objChild.data("videomp4");
20126		 		
20127		 		g_temp.isHtml5VideoPresent = true;
20128		 	break;
20129		 	case "soundcloud":
20130		 		objItem.trackid = objChild.data("trackid");
20131		 		g_temp.isSoundCloudPresent = true;
20132		 	break;
20133		 	case "wistia":
20134				 objItem.videoid = objChild.data("videoid");
20135				 g_temp.isWistiaPresent = true;
20136		 	break;
20137		 	case "custom":
20138				var objChildImage = objChild.children("img");
20139		 		
20140				if(objChildImage.length){
20141					objChildImage = jQuery(objChildImage[0]);
20142					
20143				    objItem.urlThumb = objChildImage.attr("src");
20144				    objItem.title = objChildImage.attr("alt");
20145				    objItem.objThumbImage = objChildImage;
20146		 		}
20147		 		
20148				//add additional html
20149				var objChildren = objChild.children().not("img:first-child");
20150		 		
20151				if(objChildren.length)
20152					objItem.addHtml = objChildren.clone();
20153		 		
20154		 	break;
20155		 }
20156		
20157		 //clear not needed attributes
20158		 if(objItem.objThumbImage){
20159			 objItem.objThumbImage.removeAttr("data-description", "");
20160			 objItem.objThumbImage.removeAttr("data-image", "");				 
20161			 objItem.objThumbImage.removeAttr("data-thumb", "");				 
20162			 objItem.objThumbImage.removeAttr("title", "");				 
20163		 }
20164		 
20165		 
20166		 return(objItem);
20167	}
20168	
20169	
20170	/**
20171	 * fill items array from images object
20172	 */
20173	function fillItemsArray(arrChildren, isAppend){
20174		
20175		if(isAppend !== true){
20176			g_arrItems = [];
20177		}else{	 //append
20178			
20179			//clear last new added items
20180			for(var i=0;i<g_numItems;i++)
20181				g_arrItems[i].isNewAdded = false;
20182		
20183		}
20184		 
20185		 for(var i=0;i<arrChildren.length;i++){
20186			 var objChild = jQuery(arrChildren[i]);
20187			 			 
20188			 var objItem = fillItemByChild(objChild);
20189			 numIndex = g_arrItems.length;			 
20190			 objItem.index = numIndex;
20191			 
20192			 if(isAppend === true){
20193				 objItem.isNewAdded = true;
20194			 }
20195			 
20196			 g_arrItems.push(objItem);
20197		 }
20198		 
20199		 g_numItems = g_arrItems.length;
20200		 
20201	}
20202	
20203	
20204	/**
20205	 * load api's according presented item types
20206	 */
20207	function loadAPIs(){
20208		
20209		//load youtube api
20210		if(g_temp.isYoutubePresent)
20211			g_ugYoutubeAPI.loadAPI();
20212		
20213		if(g_temp.isVimeoPresent)
20214			g_ugVimeoAPI.loadAPI();
20215		
20216		if(g_temp.isHtml5VideoPresent)
20217			g_ugHtml5MediaAPI.loadAPI();
20218		
20219		if(g_temp.isSoundCloudPresent)
20220			g_ugSoundCloudAPI.loadAPI();
20221		
20222		if(g_temp.isWistiaPresent)
20223			g_ugWistiaAPI.loadAPI();
20224		
20225	}
20226	
20227	
20228	/**
20229	 * preload big images
20230	 */
20231	function preloadBigImages(){
20232		
20233		//check and fix preload type
20234		if(g_options.gallery_images_preload_type == "visible" && !g_objThumbs)
20235			g_options.gallery_images_preload_type = "minimal";
20236		
20237		if(g_temp.isAllItemsPreloaded == true)
20238			return(true);
20239		
20240		switch(g_options.gallery_images_preload_type){
20241			default:
20242			case "minimal":
20243			break;
20244			case "all":
20245				
20246				jQuery(g_arrItems).each(function(){	
20247					preloadItemImage(this);			
20248				});			
20249				
20250			break;
20251			case "visible":
20252				jQuery(g_arrItems).each(function(){		
20253					var objItem = this;
20254					var isVisible = g_objThumbs.isItemThumbVisible(objItem);
20255					
20256					if(isVisible == true)
20257						preloadItemImage(objItem);
20258				});
20259				
20260			break;
20261		}
20262				
20263	}
20264	
20265	/**
20266	 * check if item needed to preload and preload it
20267	 */
20268	function checkPreloadItemImage(objItem){
20269		
20270		if(objItem.isBigImageLoadStarted == true ||
20271				   objItem.isBigImageLoaded == true || 
20272				   objItem.isBigImageLoadError == true){
20273					return(false);			
20274		}
20275		
20276		switch(g_options.gallery_images_preload_type){
20277			default:
20278			case "minimal":
20279			break;
20280			case "all":			
20281					preloadItemImage(objItem);							
20282			break;
20283			case "visible":
20284				var isVisible = g_objThumbs.isItemThumbVisible(objItem);					
20285					if(isVisible == true)
20286						preloadItemImage(objItem);				
20287			break;
20288		}
20289		
20290	}
20291	
20292	/**
20293	 * preload item image
20294	 */
20295	function preloadItemImage(objItem){
20296		
20297		if(objItem.isBigImageLoadStarted == true ||
20298		   objItem.isBigImageLoaded == true || 
20299		   objItem.isBigImageLoadError == true){
20300			return(true);			
20301		}
20302		
20303		var imageUrl = objItem.urlImage;
20304		if(imageUrl == "" || imageUrl == undefined){
20305			objItem.isBigImageLoadError = true;
20306			return(false);
20307		}
20308		
20309		objItem.isBigImageLoadStarted = true;
20310				
20311		objItem.objPreloadImage = jQuery('<img/>').attr("src", imageUrl);
20312		objItem.objPreloadImage.data("itemIndex", objItem.index);
20313		
20314		//set image load event (not that reliable)
20315		objItem.objPreloadImage.on("load", t.onItemBigImageLoaded);
20316		
20317		//set load error event
20318		objItem.objPreloadImage.on( "error", function(){
20319			var objImage = jQuery(this);
20320			var itemIndex = objImage.data("itemIndex");
20321			var objItem = g_arrItems[itemIndex];
20322			
20323			//update error:
20324			objItem.isBigImageLoadError = true;
20325			objItem.isBigImageLoaded = false;
20326			
20327			//print error
20328			var imageUrl = jQuery(this).attr("src");
20329			console.log("Can't load image: "+ imageUrl);
20330			
20331			//try to load the image again
20332			g_objGallery.trigger(t.events.ITEM_IMAGE_UPDATED, [itemIndex, objItem.urlImage]);
20333			objItem.objThumbImage.attr("src", objItem.urlThumb);
20334			
20335		});
20336		
20337		//check the all items started preloading flag
20338		checkAllItemsStartedPreloading();
20339		
20340	}
20341	
20342	
20343	/**
20344	 * on item big image loaded event function. 
20345	 * Update image size and that the image has been preloaded
20346	 * can be called from another objects like the slider
20347	 */
20348	this.onItemBigImageLoaded = function(event, objImage){
20349				
20350		if(!objImage)
20351			var objImage = jQuery(this);
20352		
20353		var itemIndex = objImage.data("itemIndex");
20354		
20355		var objItem = g_arrItems[itemIndex];
20356		
20357		objItem.isBigImageLoaded = true;
20358		
20359		//get size with fallback function
20360		var objSize = g_functions.getImageOriginalSize(objImage);
20361		
20362		objItem.imageWidth = objSize.width;
20363		objItem.imageHeight = objSize.height;		
20364	}
20365	
20366	/**
20367	 * check and fill image size in item object
20368	 */
20369	this.checkFillImageSize = function(objImage, objItem){
20370		
20371		if(!objItem){
20372			var itemIndex = objImage.data("itemIndex");
20373			if(itemIndex === undefined)
20374				throw new Error("Wrong image given to gallery.checkFillImageSize");
20375			
20376			var objItem = g_arrItems[itemIndex];
20377		}
20378		
20379		var objSize = g_functions.getImageOriginalSize(objImage);
20380		
20381		objItem.imageWidth = objSize.width;
20382		objItem.imageHeight = objSize.height;		
20383	}
20384	
20385	
20386	/**
20387	 * preload next images near current item
20388	 */
20389	function preloadNearBigImages(objItem){
20390		
20391		if(g_temp.isAllItemsPreloaded == true)
20392			return(false);
20393		
20394		if(!objItem)
20395			var objItem = g_selectedItem;
20396		
20397		if(!objItem)
20398			return(true);
20399			
20400		var currentIndex = objItem.index;
20401		var lastItemIndex = currentIndex - 1;
20402		var nextItemIndex = currentIndex + 1;
20403		
20404		if(lastItemIndex > 0)
20405			preloadItemImage(g_arrItems[lastItemIndex]);
20406		
20407		if(nextItemIndex < g_numItems)
20408			preloadItemImage(g_arrItems[nextItemIndex]);
20409			
20410	}
20411	
20412	
20413	/**
20414	 * check that all items started preloading, if do, set 
20415	 * flag g_temp.isAllItemsPreloaded to true
20416	 */
20417	function checkAllItemsStartedPreloading(){
20418		
20419		if(g_temp.isAllItemsPreloaded == true)
20420			return(false);
20421		
20422		//if some of the items not started, exit function:
20423		for(var index in g_arrItems){
20424			if(g_arrItems[index].isBigImageLoadStarted == false)
20425				return(false);
20426		}
20427		
20428		//if all started, set flag to true
20429		g_temp.isAllItemsPreloaded = true;	
20430	}
20431	
20432	
20433	/**
20434	 * set freestyle mode
20435	 */
20436	this.setFreestyleMode = function(){
20437		
20438		g_temp.isFreestyleMode = true;
20439	
20440	}
20441	
20442	
20443	/**
20444	 * attach thumbs panel to the gallery
20445	 */
20446	this.attachThumbsPanel = function(type, objThumbs){
20447		g_temp.thumbsType = type;
20448		g_objThumbs = objThumbs;
20449	}
20450	
20451	
20452	/**
20453	 * init the slider
20454	 */	
20455	this.initSlider = function(customOptions, optionsPrefix){
20456		 
20457		 //mix options with user options
20458		 if(!customOptions)
20459			 var customOptions = {};
20460		 		 
20461		 customOptions = jQuery.extend(g_temp.objCustomOptions, customOptions);
20462		 
20463		 g_objSlider = new UGSlider();		 
20464		 g_objSlider.init(t, customOptions, optionsPrefix);
20465	}
20466	
20467	
20468	function __________END_INIT_GALLERY_______(){};
20469	
20470	function __________EVENTS_____________(){};
20471
20472	
20473	/**
20474	 * on gallery mousewheel event handler, advance the thumbs
20475	 */
20476	this.onGalleryMouseWheel = function(event, delta, deltaX, deltaY){
20477		
20478		event.preventDefault();
20479		
20480		if(delta > 0)
20481			t.prevItem();
20482		else
20483			t.nextItem();
20484	}
20485	
20486	
20487	/**
20488	 * on mouse enter event
20489	 */
20490	function onSliderMouseEnter(event){
20491		
20492		if(g_options.gallery_pause_on_mouseover == true && t.isFullScreen() == false && g_temp.isPlayMode == true && g_objSlider && g_objSlider.isSlideActionActive() == false)
20493			t.pausePlaying();
20494	}
20495	
20496	
20497	/**
20498	 * on mouse move event
20499	 */
20500	function onSliderMouseLeave(event){
20501		
20502		if(g_options.gallery_pause_on_mouseover == true && g_temp.isPlayMode == true && g_objSlider && g_objSlider.isSlideActionActive() == false){
20503			
20504			var isStillLoading = g_objSlider.isCurrentSlideLoadingImage();
20505			
20506			if(isStillLoading == false)
20507				t.continuePlaying();
20508		}
20509		
20510	}
20511	
20512	
20513	/**
20514	 * on keypress - keyboard control
20515	 */
20516	function onKeyPress(event){
20517		 
20518		var obj = jQuery(event.target);
20519		if(obj.is("textarea") || obj.is("select") || obj.is("input"))
20520			return(true);
20521						
20522		 var keyCode = (event.charCode) ? event.charCode :((event.keyCode) ? event.keyCode :((event.which) ? event.which : 0));
20523		 
20524		 var wasAction = true;
20525		 
20526		 switch(keyCode){
20527			 case 39:	//right key
20528				 t.nextItem();
20529			 break;
20530			 case 37:	//left key
20531				 t.prevItem();
20532			 break;
20533			 default:
20534				 wasAction = false;
20535			 break; 
20536		 }
20537		 
20538		 //only first page gallery affected
20539		 
20540		 if(wasAction == true){
20541			 event.preventDefault();
20542			 event.stopPropagation();
20543			 event.stopImmediatePropagation();
20544		 }
20545		 
20546		g_objGallery.trigger(t.events.GALLERY_KEYPRESS, [keyCode,event]);
20547	}
20548	
20549	
20550	/**
20551	 * check that the gallery resized, if do, trigger onresize event
20552	 */
20553	function onGalleryResized(){
20554		
20555		var objSize = t.getSize();
20556		
20557		if(objSize.width == 0)	//fix hidden gallery change
20558			return(true);
20559		
20560		t.setSizeClass();
20561		
20562		var objSize = t.getSize();
20563		
20564		if(objSize.width != g_temp.lastWidth || (g_temp.isFreestyleMode == false && objSize.height != g_temp.lastHeight)){
20565			
20566			var heightWasSet = false;
20567			
20568			//set height with custom function (if exists)
20569			if(g_temp.funcCustomHeight){
20570				var newHeight = g_temp.funcCustomHeight(objSize);
20571				if(newHeight){
20572					g_objWrapper.height(newHeight);
20573					heightWasSet = true;
20574				}
20575			}
20576			
20577			if(heightWasSet == false && g_options.gallery_preserve_ratio == true && g_temp.isFreestyleMode == false)
20578				setHeightByOriginalRatio();
20579			
20580			storeLastSize();
20581			g_objGallery.trigger(t.events.SIZE_CHANGE);
20582			
20583		}
20584		
20585	}
20586
20587	
20588	/**
20589	 * on strip move event
20590	 * preload visible images if that option selected
20591	 */
20592	function onThumbsChange(event){
20593		
20594		//preload visible images 
20595		if(g_options.gallery_images_preload_type == "visible" && g_temp.isAllItemsPreloaded == false){
20596			preloadBigImages();
20597		}
20598		
20599	}
20600	
20601	
20602	/**
20603	 * on full screen change event
20604	 */
20605	function onFullScreenChange(){
20606		
20607		
20608		var isFullscreen = g_functions.isFullScreen();
20609		var event = isFullscreen ? t.events.ENTER_FULLSCREEN:t.events.EXIT_FULLSCREEN; 
20610
20611		 var fullscreenID = g_functions.getGlobalData("fullscreenID");
20612		 
20613		 //check if this gallery was affected
20614		 if(g_galleryID !== fullscreenID)
20615			 return(true);
20616		 		 
20617		 //add classes for the gallery
20618		 if(isFullscreen){
20619			 g_objWrapper.addClass("ug-fullscreen");
20620		 }else{
20621			 g_objWrapper.removeClass("ug-fullscreen");
20622		 }
20623
20624		 g_objGallery.trigger(event);
20625		 
20626		 onGalleryResized();
20627	}
20628	
20629	/**
20630	 * on big image updated, if needed - preload this item image
20631	 */
20632	function onItemImageUpdated(event, index){
20633		
20634		var objItem = t.getItem(index);		
20635		checkPreloadItemImage(objItem);		
20636	}
20637	
20638	/**
20639	 * on current slide image load end. If playing mode, begin playing again
20640	 */
20641	function onCurrentSlideImageLoadEnd(){
20642		
20643		if(t.isPlayMode() == true)
20644			t.continuePlaying();
20645	}
20646		
20647	
20648	/**
20649	 * init all events
20650	 */
20651	function initEvents(){
20652		
20653		//avoid annoyong firefox image dragging
20654		g_objWrapper.on("dragstart",function(event){
20655			event.preventDefault();
20656		});
20657		
20658		//on big image updated, if needed - preload this item image
20659		g_objGallery.on(t.events.ITEM_IMAGE_UPDATED, onItemImageUpdated);
20660		
20661		//init custom event on strip moving
20662		if(g_objThumbs){
20663			switch(g_temp.thumbsType){
20664				case "strip":
20665					jQuery(g_objThumbs).on(g_objThumbs.events.STRIP_MOVE, onThumbsChange);
20666				break;
20667				case "grid":
20668					jQuery(g_objThumbs).on(g_objThumbs.events.PANE_CHANGE, onThumbsChange);
20669				break;
20670			}
20671		}
20672		
20673		//init mouse wheel
20674		if(g_options.gallery_mousewheel_role == "advance" && g_temp.isFreestyleMode == false)
20675			g_objWrapper.on("mousewheel", t.onGalleryMouseWheel);
20676		
20677		 //on resize event
20678		 storeLastSize();
20679		 
20680		 jQuery(window).resize(function(){
20681			 g_objWrapper.css("width","auto");
20682			 g_functions.whenContiniousEventOver("gallery_resize", onGalleryResized, g_temp.resizeDelay);
20683		 });
20684		 
20685		 //check resize once in a time, start from 10 seconds
20686		 setTimeout(function(){
20687			 setInterval(onGalleryResized, 2000);
20688		 }, 10000);
20689		 
20690		 //fullscreen:
20691		 g_functions.addFullScreenChangeEvent(onFullScreenChange);
20692		 
20693		 //on slider item changed event
20694		 if(g_objSlider){
20695			 
20696			 jQuery(g_objSlider).on(g_objSlider.events.ITEM_CHANGED, function(){
20697				 var sliderIndex = g_objSlider.getCurrentItemIndex();
20698				 				 
20699				 if(sliderIndex != -1)
20700					 t.selectItem(sliderIndex);
20701			 });
20702			 
20703			 //add slider onmousemove event
20704			 if(g_options.gallery_pause_on_mouseover == true){
20705				 var sliderElement = g_objSlider.getElement();
20706				 sliderElement.hover(onSliderMouseEnter, onSliderMouseLeave);
20707				 
20708				 //on full screen, run on mouse leave
20709				 g_objGallery.on(t.events.ENTER_FULLSCREEN, function(){
20710						 onSliderMouseLeave();
20711				 });
20712				 
20713			 }
20714			 
20715			 //retrigger slider events
20716			 retriggerEvent(g_objSlider, g_objSlider.events.ACTION_START, t.events.SLIDER_ACTION_START);
20717			 retriggerEvent(g_objSlider, g_objSlider.events.ACTION_END, t.events.SLIDER_ACTION_END);
20718			 
20719			 jQuery(g_objSlider).on(g_objSlider.events.CURRENTSLIDE_LOAD_END, onCurrentSlideImageLoadEnd);
20720			 
20721		 }
20722		  
20723		 //add keyboard events
20724		 if(g_options.gallery_control_keyboard == true)
20725			 jQuery(document).keydown(onKeyPress);
20726		 		 
20727	}
20728	
20729	
20730	/**
20731	 * destroy all gallery events
20732	 */
20733	this.destroy = function(){
20734		
20735		g_objWrapper.off("dragstart");
20736		g_objGallery.off(t.events.ITEM_IMAGE_UPDATED);
20737		
20738		//init custom event on strip moving
20739		if(g_objThumbs){
20740			switch(g_temp.thumbsType){
20741				case "strip":
20742					jQuery(g_objThumbs).off(g_objThumbs.events.STRIP_MOVE);
20743				break;
20744				case "grid":
20745					jQuery(g_objThumbs).off(g_objThumbs.events.PANE_CHANGE);
20746				break;
20747			}
20748		}
20749		
20750		 g_objWrapper.off("mousewheel");
20751		
20752		 jQuery(window).off("resize");
20753		 
20754		 //fullscreen:
20755		 g_functions.destroyFullScreenChangeEvent();
20756		 
20757		 //on slider item changed event
20758		 if(g_objSlider){
20759			 
20760			 jQuery(g_objSlider).off(g_objSlider.events.ITEM_CHANGED);
20761			 
20762			 //add slider onmousemove event
20763			 var sliderElement = g_objSlider.getElement();
20764			 sliderElement.off("mouseenter");
20765			 sliderElement.off("mouseleave");
20766			 
20767			 g_objGallery.off(t.events.ENTER_FULLSCREEN);
20768			 jQuery(g_objSlider).off(g_objSlider.events.ACTION_START);
20769			 jQuery(g_objSlider).off(g_objSlider.events.ACTION_END);
20770			 jQuery(g_objSlider).off(g_objSlider.events.CURRENTSLIDE_LOAD_END);
20771		 }
20772		 		 
20773		 //add keyboard events
20774		 if(g_options.gallery_control_keyboard == true)
20775			 jQuery(document).off("keydown");
20776		
20777		 //destroy theme
20778		 if(g_objTheme && typeof g_objTheme.destroy == "function"){
20779			 g_objTheme.destroy();
20780		 }
20781		 
20782		 g_objWrapper.html("");
20783		 
20784	}
20785	
20786	
20787	function __________GENERAL_______(){};
20788	
20789	/**
20790	 * get items array
20791	 */
20792	this.getArrItems = function(){
20793		return g_arrItems;
20794	}
20795	
20796	/**
20797	 * get gallery objects
20798	 */
20799	this.getObjects = function(){
20800			
20801		var objects = {
20802			g_galleryID:g_galleryID,
20803			g_objWrapper:g_objWrapper,
20804			g_objThumbs:g_objThumbs,
20805			g_objSlider:g_objSlider,
20806			g_options:g_options,
20807			g_arrItems:g_arrItems,
20808			g_numItems:g_numItems
20809		};
20810		
20811		return(objects);
20812	}
20813	
20814	/**
20815	 * get slider object
20816	 */
20817	this.getObjSlider = function(){
20818		
20819		return(g_objSlider);
20820	}
20821	
20822	
20823	/**
20824	 * 
20825	 * get item by index, if the index don't fit, trace error
20826	 */
20827	this.getItem = function(index){
20828		if(index < 0){
20829			throw new Error("item with index: " + index + " not found");
20830			return(null);
20831		}
20832		if(index >= g_numItems){
20833			throw new Error("item with index: " + index + " not found");
20834			return(null);			
20835		}
20836		
20837		return(g_arrItems[index]);
20838	}
20839	
20840	
20841	/**
20842	 * get gallery width
20843	 */
20844	this.getWidth = function(){
20845		
20846		var objSize = t.getSize();
20847				
20848		return(objSize.width);
20849	}
20850	
20851	/**
20852	 * get gallery height
20853	 */
20854	this.getHeight = function(){
20855		
20856		var objSize = t.getSize();
20857		
20858		return(objSize.height);
20859	}
20860	
20861	
20862	/**
20863	 * get gallery size
20864	 */
20865	this.getSize = function(){
20866		
20867		var objSize = g_functions.getElementSize(g_objWrapper);
20868		
20869		objSize.orig_width = g_options.gallery_width;
20870		objSize.orig_height = g_options.gallery_height;
20871		objSize.orig_ratio = objSize.orig_width / objSize.orig_height;
20872		
20873		return(objSize);
20874	}
20875	
20876	/**
20877	 * get gallery ID
20878	 */
20879	this.getGalleryID = function(){
20880		
20881		var id = g_galleryID.replace("#","");
20882			
20883		return(id);
20884	}
20885	
20886	/**
20887	 * get next item by current index (or current object)
20888	 */
20889	this.getNextItem = function(index, forceCarousel){
20890		
20891		if(typeof index == "object")
20892			index = index.index;
20893		
20894		var nextIndex = index + 1;
20895		
20896		if(forceCarousel !== true && g_numItems == 1)
20897			return(null);
20898		
20899		if(nextIndex >= g_numItems){
20900			
20901			if(g_options.gallery_carousel == true || forceCarousel === true)
20902				nextIndex = 0;
20903			else
20904				return(null);
20905		}
20906		
20907		var objItem = g_arrItems[nextIndex];
20908		
20909		return(objItem);			
20910	}
20911	
20912	
20913	/**
20914	 * get previous item by index (or item object)
20915	 */
20916	this.getPrevItem = function(index){
20917		
20918		if(typeof index == "object")
20919			index = index.index;
20920		
20921		var prevIndex = index - 1;
20922		
20923		if(prevIndex < 0){
20924			if(g_options.gallery_carousel == true || forceCarousel === true)
20925				prevIndex = g_numItems - 1;
20926			else
20927				return(null);
20928		}
20929		
20930		var objItem = g_arrItems[prevIndex];
20931		
20932		return(objItem);
20933	}
20934	
20935	
20936	
20937	/**
20938	 * get selected item
20939	 */
20940	this.getSelectedItem = function(){
20941		
20942		return(g_selectedItem);
20943	}
20944	
20945	/**
20946	 * get selected item index
20947	 */
20948	this.getSelectedItemIndex = function(){
20949		
20950		return(g_selectedItemIndex);
20951	}
20952	
20953	
20954	/**
20955	 * get number of items
20956	 */
20957	this.getNumItems = function(){
20958		return g_numItems;
20959	}
20960	
20961	/**
20962	 * get true if the current item is last
20963	 */
20964	this.isLastItem = function(){
20965		if(g_selectedItemIndex == g_numItems - 1)
20966			return(true);
20967		
20968		return(false);
20969	}
20970	
20971	
20972	/**
20973	 * get true if the current item is first
20974	 */
20975	this.isFirstItem = function(){
20976		if(g_selectedItemIndex == 0)
20977			return(true);
20978		return(false);
20979	}
20980	
20981		
20982	/**
20983	 * get gallery options
20984	 */
20985	this.getOptions = function(){
20986		return g_options;
20987	}
20988	
20989	
20990	/**
20991	 * get the gallery wrapper element
20992	 */
20993	this.getElement = function(){
20994		return(g_objWrapper);
20995	}
20996	
20997	
20998	this.___________SET_CONTROLS___________ = function(){}
20999	
21000	/**
21001	 * set next button element
21002	 * set onclick event
21003	 */
21004	this.setNextButton = function(objButton){
21005		
21006		//register button as a unite gallery belong
21007		objButton.data("ug-button", true);
21008		
21009		g_functions.setButtonOnClick(objButton, t.nextItem);
21010		
21011	}
21012	
21013	
21014	/**
21015	 * set prev button element
21016	 * set onclick event
21017	 */
21018	this.setPrevButton = function(objButton){
21019		
21020		//register button as a unite gallery belong
21021		objButton.data("ug-button", true);
21022		
21023		g_functions.setButtonOnClick(objButton, t.prevItem);
21024				
21025	}
21026	
21027	
21028	/**
21029	 * set fullscreen button to enter / exit fullscreen.
21030	 * on fullscreen mode ug-fullscreenmode class wil be added
21031	 */
21032	this.setFullScreenToggleButton = function(objButton){
21033		
21034		//register button as a unite gallery belong
21035		objButton.data("ug-button", true);
21036
21037		g_functions.setButtonOnTap(objButton, t.toggleFullscreen);
21038		
21039		g_objGallery.on(t.events.ENTER_FULLSCREEN,function(){
21040			objButton.addClass("ug-fullscreenmode");
21041		});
21042		
21043		g_objGallery.on(t.events.EXIT_FULLSCREEN,function(){
21044			objButton.removeClass("ug-fullscreenmode");
21045		});
21046				
21047	}
21048	
21049	
21050	/**
21051	 * destroy full screen button
21052	 */
21053	this.destroyFullscreenButton = function(objButton){
21054		
21055		g_functions.destroyButton(objButton);
21056		
21057		g_objGallery.off(t.events.ENTER_FULLSCREEN);
21058		g_objGallery.off(t.events.EXIT_FULLSCREEN);
21059	}
21060	
21061	
21062	/**
21063	 * set play button event
21064	 */
21065	this.setPlayButton = function(objButton){
21066		
21067		//register button as a unite gallery belong
21068		objButton.data("ug-button", true);
21069		
21070		g_functions.setButtonOnClick(objButton, t.togglePlayMode);
21071		
21072		g_objGallery.on(t.events.START_PLAY,function(){
21073			objButton.addClass("ug-stop-mode");
21074		});
21075		
21076		g_objGallery.on(t.events.STOP_PLAY, function(){
21077			objButton.removeClass("ug-stop-mode");
21078		});
21079		
21080	}
21081	
21082	/**
21083	 * destroy the play button
21084	 */
21085	this.destroyPlayButton = function(objButton){
21086		g_functions.destroyButton(objButton);
21087		g_objGallery.off(t.events.START_PLAY);
21088		g_objGallery.off(t.events.STOP_PLAY);
21089	}
21090	
21091	/**
21092	 * set playing progress indicator
21093	 */
21094	this.setProgressIndicator = function(objProgress){
21095		
21096		g_temp.objProgress = objProgress;		
21097	}
21098	
21099	
21100	/**
21101	 * set title and descreiption containers
21102	 */
21103	this.setTextContainers = function(objTitle, objDescription){
21104		
21105		g_objGallery.on(t.events.ITEM_CHANGE, function(){
21106			
21107			var objItem = t.getSelectedItem();			
21108			objTitle.html(objItem.title);
21109			objDescription.html(objItem.description);
21110			
21111		});
21112		
21113	}
21114	
21115	/**
21116	 * show overlay disabled
21117	 */
21118	this.showDisabledOverlay = function(){
21119		g_objWrapper.children(".ug-overlay-disabled").show();
21120	}
21121
21122	/**
21123	 * show overlay disabled
21124	 */
21125	this.hideDisabledOverlay = function(){
21126		g_objWrapper.children(".ug-overlay-disabled").hide();
21127	}
21128	
21129	this.___________END_SET_CONTROLS___________ = function(){}
21130
21131	
21132	/**
21133	 * cache items, put to cache array by id
21134	 * the items must be unprocessed yet
21135	 */
21136	function cacheItems(cacheID, htmlItemsArg){
21137			
21138		if(htmlItemsArg){
21139			var htmlItems = htmlItemsArg;
21140			if(htmlItems != "noitems")
21141				htmlItems = jQuery(htmlItemsArg).clone();
21142		}else{
21143			var htmlItems = g_objWrapper.children().clone();
21144		}
21145		
21146		g_objCache[cacheID] = htmlItems;
21147	}
21148	
21149	
21150	/**
21151	 * remove all size classes
21152	 */
21153	function removeAllSizeClasses(objWrapper){
21154		
21155		if(!objWrapper)
21156			objWrapper = g_objWrapper;
21157		
21158		objWrapper.removeClass("ug-under-480");
21159		objWrapper.removeClass("ug-under-780");
21160		objWrapper.removeClass("ug-under-960");
21161	}
21162	
21163	
21164	/**
21165	 * retrigger event from another objects
21166	 * the second parameter will be the second object
21167	 */
21168	function retriggerEvent(object, originalEvent, newEvent){
21169		
21170		jQuery(object).on(originalEvent, function(event){
21171			g_objGallery.trigger(newEvent, [this]);
21172		});
21173	
21174	}
21175	
21176	
21177	
21178	/**
21179	 * advance next play step
21180	 */
21181	function advanceNextStep(){
21182		
21183		var timeNow = jQuery.now();
21184		var timeDiff = timeNow - g_temp.playTimeLastStep;
21185		g_temp.playTimeLastStep = timeNow;
21186		
21187		var isVisible = t.isGalleryVisible();
21188		if(isVisible == false){
21189			return(false);
21190		}
21191		
21192		g_temp.playTimePassed += timeDiff;
21193		
21194		//set the progress
21195		if(g_temp.objProgress){
21196			var percent = g_temp.playTimePassed / g_options.gallery_play_interval;
21197			g_temp.objProgress.setProgress(percent);
21198		}
21199		
21200		//if interval passed - proceed to next item
21201		if(g_temp.playTimePassed >= g_options.gallery_play_interval){
21202			
21203			t.nextItem();
21204			g_temp.playTimePassed = 0;			
21205		}
21206		
21207		
21208	}
21209	
21210	this.___________PLAY_MODE___________ = function(){}
21211	
21212	
21213	/**
21214	 * start play mode
21215	 */
21216	this.startPlayMode = function(){
21217		
21218		g_temp.isPlayMode = true;
21219		g_temp.isPlayModePaused = false;
21220		
21221		g_temp.playTimePassed = 0;
21222		g_temp.playTimeLastStep = jQuery.now();
21223		
21224		g_temp.playHandle = setInterval(advanceNextStep, g_temp.playStepInterval);
21225		
21226		//show and reset progress indicator
21227		if(g_temp.objProgress){
21228			var objElement = g_temp.objProgress.getElement();
21229			g_temp.objProgress.setProgress(0);
21230			objElement.show();
21231		}
21232		
21233		g_objGallery.trigger(t.events.START_PLAY);
21234		
21235		//check if there is a need to pause
21236		if(g_objSlider && g_objSlider.isCurrentSlideLoadingImage() == true){
21237			t.pausePlaying();
21238		}
21239		
21240	}
21241	
21242	
21243	/**
21244	 * reset playing - set the timer to 0
21245	 */
21246	this.resetPlaying = function(){
21247		
21248		if(g_temp.isPlayMode == false)
21249			return(true);
21250		
21251		g_temp.playTimePassed = 0;
21252		g_temp.playTimeLastStep = jQuery.now();
21253	}
21254	
21255	
21256	/**
21257	 * pause playing slideshow
21258	 */
21259	this.pausePlaying = function(){
21260		
21261		if(g_temp.isPlayModePaused == true)
21262			return(true);
21263		
21264		g_temp.isPlayModePaused = true;
21265		clearInterval(g_temp.playHandle);
21266		
21267		g_objGallery.trigger(t.events.PAUSE_PLAYING);
21268	}
21269	
21270	
21271	/**
21272	 * continue playing slideshow
21273	 */
21274	this.continuePlaying = function(){
21275		
21276		if(g_temp.isPlayModePaused == false)
21277			return(true);
21278		
21279		g_temp.isPlayModePaused = false;
21280		g_temp.playTimeLastStep = jQuery.now();
21281		g_temp.playHandle = setInterval(advanceNextStep, g_temp.playStepInterval);
21282		
21283	}
21284	
21285	
21286	/**
21287	 * stop play mode
21288	 */
21289	this.stopPlayMode = function(){
21290		g_temp.isPlayMode = false;
21291		clearInterval(g_temp.playHandle);
21292			
21293		g_temp.playTimePassed = 0;
21294		
21295		//hide progress indicator
21296		if(g_temp.objProgress){
21297			var objElement = g_temp.objProgress.getElement();
21298			objElement.hide();
21299		}
21300		
21301		g_objGallery.trigger(t.events.STOP_PLAY);
21302	}
21303	
21304	
21305	/**
21306	 * tells if the play mode are active
21307	 */
21308	this.isPlayMode = function(){
21309		
21310		return(g_temp.isPlayMode);
21311	}
21312	
21313	
21314	/**
21315	 * start / stop play mode
21316	 */
21317	this.togglePlayMode = function(){
21318		
21319		if(t.isPlayMode() == false)
21320			t.startPlayMode();
21321		else
21322			t.stopPlayMode();
21323	}
21324
21325	
21326	/**
21327	 * unselect all items
21328	 */
21329	function unselectSeletedItem(){
21330		
21331		if(g_selectedItem == null)
21332			return(true);
21333		
21334		if(g_objThumbs)
21335			g_objThumbs.setThumbUnselected(g_selectedItem.objThumbWrapper);
21336		
21337		g_selectedItem = null;
21338		g_selectedItemIndex = -1;
21339	}	
21340	
21341	
21342	this.___________GENERAL_EXTERNAL___________ = function(){}
21343	
21344	/**
21345	 * shuffle items - usually before theme start
21346	 */
21347	this.shuffleItems = function(){
21348
21349		g_arrItems = g_functions.arrayShuffle(g_arrItems);
21350		
21351		for(var index in g_arrItems)		//fix index
21352			g_arrItems[index].index = parseInt(index);
21353		
21354	}
21355	
21356	/**
21357	 * set main gallery params, extend current params
21358	 */
21359	this.setOptions = function(customOptions){
21360				
21361		g_options = jQuery.extend(g_options, customOptions);		
21362	}
21363	
21364	
21365	/**
21366	 * select some item
21367	 * the input can be index or object
21368	 * role - the role of the object who selected the item
21369	 */
21370	this.selectItem = function(objItem, role){
21371		
21372		if(typeof objItem == "number")
21373			objItem = t.getItem(objItem);
21374		
21375		var itemIndex = objItem.index;
21376		if(itemIndex == g_selectedItemIndex)
21377			return(true);
21378				
21379		unselectSeletedItem();
21380				
21381		//set selected item
21382		g_selectedItem = objItem;		
21383		g_selectedItemIndex = itemIndex;
21384		
21385		g_objGallery.trigger(t.events.ITEM_CHANGE, [objItem,role]);
21386		
21387		//reset playback, if playing
21388		if(g_temp.isPlayMode == true){
21389				t.resetPlaying();
21390			
21391			var stillLoading = g_objSlider.isCurrentSlideLoadingImage();
21392			if(stillLoading == true)
21393				t.pausePlaying();
21394		}
21395				
21396	}
21397	
21398	
21399	/**
21400	 * go to next item
21401	 */
21402	this.nextItem = function(){
21403		
21404		var newItemIndex = g_selectedItemIndex + 1;
21405		
21406		if(g_numItems == 0)
21407			return(true);		
21408		
21409		if(g_options.gallery_carousel == false && newItemIndex >= g_numItems)
21410			return(true);
21411		
21412		if(newItemIndex >= g_numItems)
21413			newItemIndex = 0;
21414		
21415		//debugLine(newItemIndex,true);
21416		
21417		t.selectItem(newItemIndex, "next");
21418	}
21419	
21420	
21421	/**
21422	 * go to previous item
21423	 */
21424	this.prevItem = function(){
21425		
21426		var newItemIndex = g_selectedItemIndex - 1;
21427		
21428		if(g_selectedItemIndex == -1)
21429			newItemIndex = 0;
21430		
21431		if(g_numItems == 0)
21432			return(true);
21433		
21434		if(g_options.gallery_carousel == false && newItemIndex < 0)
21435			return(true);
21436		
21437		if(newItemIndex < 0)
21438			newItemIndex = g_numItems - 1;
21439		
21440		t.selectItem(newItemIndex, "prev");
21441		
21442	}
21443	
21444	
21445	/**
21446	 * expand gallery to body size
21447	 */
21448	function toFakeFullScreen(){
21449		
21450		jQuery("body").addClass("ug-body-fullscreen");
21451		g_objWrapper.addClass("ug-fake-fullscreen");
21452		
21453		g_temp.isFakeFullscreen = true;
21454		
21455		g_objGallery.trigger(t.events.ENTER_FULLSCREEN);
21456		g_objGallery.trigger(t.events.SIZE_CHANGE);
21457	}
21458	
21459	
21460	/**
21461	 * exit fake fullscreen
21462	 */
21463	function exitFakeFullscreen(){
21464		
21465		jQuery("body").removeClass("ug-body-fullscreen");
21466		g_objWrapper.removeClass("ug-fake-fullscreen");
21467		
21468		g_temp.isFakeFullscreen = false;
21469		
21470		g_objGallery.trigger(t.events.EXIT_FULLSCREEN);
21471		g_objGallery.trigger(t.events.SIZE_CHANGE);
21472		
21473	}
21474	
21475	/**
21476	 * return if the fullscreen mode is available
21477	 */
21478	this.isFullScreen = function(){
21479		
21480		if(g_temp.isFakeFullscreen == true)
21481			return(true);
21482		
21483		if(g_functions.isFullScreen() == true)
21484			return(true);
21485		
21486		return(false);		
21487	}
21488	
21489	
21490	/**
21491	 * tells if it's fake fullscreen
21492	 */
21493	this.isFakeFullscreen = function(){
21494		
21495		return(g_temp.isFakeFullscreen);
21496	}
21497	
21498	
21499	/**
21500	 * go to fullscreen mode
21501	 */
21502	this.toFullScreen = function(){
21503		
21504		g_functions.setGlobalData("fullscreenID", g_galleryID);
21505		
21506		var divGallery = g_objWrapper.get(0);
21507		
21508		var isSupported = g_functions.toFullscreen(divGallery);
21509				
21510		if(isSupported == false)
21511			toFakeFullScreen();
21512		
21513	}
21514	
21515	
21516	/**
21517	 * exit full screen
21518	 */
21519	this.exitFullScreen = function(){
21520		
21521		if(g_temp.isFakeFullscreen == true)
21522			exitFakeFullscreen();
21523		else
21524			g_functions.exitFullscreen();
21525						
21526	}
21527	
21528	/**
21529	 * toggle fullscreen
21530	 */
21531	this.toggleFullscreen = function(){
21532		
21533		if(t.isFullScreen() == false){
21534			t.toFullScreen();
21535		}else{
21536			t.exitFullScreen();
21537		}
21538		
21539	}
21540	
21541	/**
21542	 * resize the gallery
21543	 * noevent - initally false
21544	 */
21545	this.resize = function(newWidth, newHeight, noevent){
21546		
21547		g_objWrapper.css("width", "auto");
21548		g_objWrapper.css("max-width",newWidth+"px");
21549		
21550		if(newHeight)
21551			g_objWrapper.height(newHeight);
21552		
21553		if(!noevent && noevent !== true)
21554			onGalleryResized();
21555		
21556	}
21557
21558	
21559	/**
21560	 * set size class to the wrapper
21561	 * this can work to any other wrapper too
21562	 */
21563	this.setSizeClass = function(objWrapper, width){
21564		
21565		if(!objWrapper)
21566			var objWrapper = g_objWrapper;
21567		
21568		if(!width){
21569			var objSize = t.getSize();
21570			var width = objSize.width;			
21571		}
21572		
21573		if(width == 0)
21574			var width = jQuery(window).width();
21575		
21576		var addClass = "";
21577		
21578		if(width <= 480){
21579			addClass = "ug-under-480";			
21580		}else
21581		if(width <= 780){
21582			addClass = "ug-under-780";			
21583		}else
21584		if(width < 960){
21585			addClass = "ug-under-960";
21586		}
21587		
21588		if(objWrapper.hasClass(addClass) == true)
21589			return(true);
21590		
21591		removeAllSizeClasses(objWrapper);
21592		if(addClass != "")
21593			objWrapper.addClass(addClass);
21594	}
21595	
21596	
21597	/**
21598	 * return if the size is suited for mobile
21599	 */
21600	this.isMobileMode = function(){
21601		
21602		if(g_objWrapper.hasClass("ug-under-480"))
21603			return(true);
21604		
21605		return(false);
21606	}
21607	
21608	
21609	/**
21610	 * get if small screen
21611	 */
21612	this.isSmallWindow = function(){
21613		
21614		var windowWidth = jQuery(window).width();
21615		
21616		
21617		if(!windowWidth)
21618			return(true);
21619		
21620		if(windowWidth <= 480)
21621			return(true);
21622		
21623		return(false);
21624	}
21625	
21626	
21627	/**
21628	 * check if the gallery is visible
21629	 */
21630	this.isGalleryVisible = function(){
21631		
21632		var isVisible = g_objWrapper.is(":visible");
21633		
21634		return(isVisible);
21635	}
21636	
21637	
21638	/**
21639	 * change gallery items
21640	 */
21641	this.changeItems = function(itemsContent, cacheID){
21642		
21643		if(!itemsContent)
21644			var itemsContent = "noitems";
21645		
21646		runGallery(g_galleryID, "nochange", itemsContent, cacheID);
21647	}
21648	
21649	
21650	
21651	/**
21652	 * add items
21653	 */
21654	this.addItems = function(itemsContent){
21655		 
21656		 if(!itemsContent || itemsContent.length == 0)
21657			 return(false);
21658		 
21659		 //add new items wrapper
21660		 var objNewItemsWrapper = g_objWrapper.children(".ug-newitems-wrapper");
21661		 if(objNewItemsWrapper.length == 0)
21662			 g_objWrapper.append("<div class='ug-newitems-wrapper' style='display:none'></div>");
21663		 
21664		 objNewItemsWrapper = g_objWrapper.children(".ug-newitems-wrapper");
21665		 
21666		 //add the items
21667		 objNewItemsWrapper.append(itemsContent);
21668		 
21669		 var objChildren = jQuery(objNewItemsWrapper.children());
21670		  
21671		 fillItemsArray(objChildren, true);
21672		 
21673		 loadAPIs();
21674		 
21675		 if(!g_objTheme || typeof g_objTheme.addItems != "function")
21676			 throw new Error("addItems function not found in the theme");
21677		 
21678		 objNewItemsWrapper.remove();
21679		 
21680		 g_objTheme.addItems();
21681	}
21682	
21683	
21684	/**
21685	 * get new added items indexes array
21686	 */
21687	this.getNewAddedItemsIndexes = function(){
21688		
21689		var arrIndexes = [];
21690		
21691		jQuery.each(g_arrItems, function(index, objItem){
21692			
21693			if(objItem.isNewAdded == true)
21694				arrIndexes.push(index);
21695		});
21696		
21697		return(arrIndexes);
21698	}
21699	
21700	
21701	/**
21702	 * show error message, replace whole gallery div
21703	 */
21704	this.showErrorMessageReplaceGallery = function(message){
21705		showErrorMessage(message);
21706	}
21707	
21708	/**
21709	 * set custom height function by width
21710	 */
21711	this.setFuncCustomHeight = function(func){
21712		g_temp.funcCustomHeight = func;
21713	}
21714	
21715	
21716	this.__________EXTERNAL_EVENTS_______ = function(){};
21717	
21718	
21719	/**
21720	 * trigger event
21721	 */
21722	this.triggerEvent = function(event, arrParams){
21723		
21724		if(!arrParams)
21725			g_objGallery.trigger(event);
21726		else{
21727			if(jQuery.type(arrParams) != "array")
21728				arrParams = [arrParams];
21729			
21730			g_objGallery.trigger(event, arrParams);
21731		}
21732		
21733	}
21734	
21735	/**
21736	 * on event
21737	 */
21738	this.onEvent = function(event, func){
21739		
21740		g_objGallery.on(event, func);
21741	}
21742	
21743	
21744	/**
21745	 * destroy event
21746	 */
21747	this.destroyEvent = function(event){
21748		
21749		g_objGallery.off(event);
21750	}
21751	
21752	
21753	this.__________AJAX_REQUEST_______ = function(){};
21754	
21755	
21756	/**
21757	 * ajax request
21758	 */
21759	this.ajaxRequest = function(action, data, successFunction, errorFunction){
21760		
21761		if(!successFunction || typeof successFunction != "function")
21762			throw new Error("ajaxRequest error: success function should be passed");
21763				
21764		var urlAjax = g_options.gallery_urlajax;
21765		if(!urlAjax || urlAjax == "")
21766			throw new Error("ajaxRequest error: Ajax url don't passed");
21767		
21768		if(typeof data == "undefined")
21769			var data = {};
21770
21771		//add galleryID to data
21772		var objData = {
21773				action:"unitegallery_ajax_action",
21774				client_action:action,
21775				galleryID: g_galleryID,
21776				data:data
21777		};
21778		
21779		jQuery.ajax({
21780			type:"post",
21781			url:g_options.gallery_urlajax,
21782			dataType: 'json',
21783			data:objData,
21784			success:function(response){
21785				
21786				if(!response){
21787					throw new Error("Empty ajax response!");
21788				}
21789
21790				if(response == -1 || response === 0)
21791					throw new Error("ajax error!!!");
21792				
21793
21794				if(typeof response.success == "undefined")
21795					throw new Error("ajax error!!!");
21796				
21797				if(response.success == false){
21798					showErrorMessage(response.message, "ajax error");
21799					return(false);
21800				}
21801				
21802				successFunction(response);
21803			},
21804			error:function(jqXHR, textStatus, errorThrown){
21805				console.log("Ajax Error!!! " + textStatus);
21806				responseText = jqXHR.responseText;
21807				if(errorFunction && typeof errorFunction == "function"){
21808					errorFunction(responseText);
21809				}else
21810					trace(responseText);
21811			}
21812		});
21813		
21814	}
21815	
21816	
21817	/**
21818	 * request new items
21819	 * isForce - don't take from cache
21820	 */
21821	this.requestNewItems = function(catID, isForce, cacheID){
21822		
21823		var checkCache = g_options.gallery_enable_cache;
21824		
21825		if(!cacheID)
21826			cacheID = catID;
21827		
21828		if(isForce == true)
21829			checkCache = false;
21830		
21831		//get items from cache
21832		if(checkCache == true && g_objCache.hasOwnProperty(cacheID)){
21833			
21834			var htmlItems = g_objCache[cacheID];
21835			
21836			t.changeItems(htmlItems, cacheID);
21837			
21838		}else{
21839			
21840			g_objGallery.trigger(t.events.GALLERY_BEFORE_REQUEST_ITEMS);
21841			
21842			t.ajaxRequest("front_get_cat_items",{catid:catID}, function(response){
21843				
21844				var htmlItems = response.html;
21845				
21846				t.changeItems(htmlItems, cacheID);
21847				
21848			});
21849			
21850		}
21851		
21852	}
21853	
21854	
21855	/**
21856	 * run the gallery
21857	 */
21858	 this.run = function(galleryID, objParams){
21859		 
21860		 
21861		 var debug_errors = g_options.gallery_debug_errors;
21862		 if(objParams && objParams.hasOwnProperty("gallery_debug_errors"))
21863			 g_options.gallery_debug_errors = objParams.gallery_debug_errors;
21864
21865		 
21866		 if(g_options.gallery_debug_errors == true){
21867			 
21868			 try{
21869				 
21870				 runGallery(galleryID, objParams);
21871				 
21872				 
21873			 }catch(objError){
21874				 if(typeof objError == "object"){
21875					 
21876					 var message = objError.message;
21877					 var lineNumber = objError.lineNumber;
21878					 var fileName = objError.fileName;
21879					 var stack = objError.stack;
21880					 
21881					 message += " <br><br> in file: "+fileName;
21882					 message += " <b> line " + lineNumber + "</b>";
21883					 
21884					 trace(objError);
21885					 
21886				 }else{
21887					 var message = objError;
21888				 }
21889				 
21890				 //remove double "error:" text
21891				 message = message.replace("Error:","");
21892				 
21893				 showErrorMessage(message);
21894			 }
21895			 
21896		 }else{
21897			 runGallery(galleryID, objParams);
21898		 }
21899		 
21900		 		 
21901		 
21902	 }
21903	 	 	 
21904}	//unitegallery object end
21905
21906
21907/**
21908 * tiles class
21909 */
21910function UGLightbox(){
21911
21912	var t = this, g_objThis = jQuery(this);
21913	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objWrapper;
21914	var g_objSlider = new UGSlider(), g_objOverlay, g_objArrowLeft, g_objArrowRight, g_objButtonClose;
21915	var g_functions = new UGFunctions(), g_objTextPanel = new UGTextPanel(), g_objNumbers;
21916	var g_objTopPanel;
21917	
21918	var g_options = {
21919			lightbox_type: "wide",							//compact / wide - lightbox type
21920			
21921			lightbox_show_textpanel: true,					//show the text panel
21922			lightbox_textpanel_width: 550,					//the width of the text panel.
21923			
21924			lightbox_hide_arrows_onvideoplay: true,			//hide the arrows when video start playing and show when stop
21925			lightbox_arrows_position: "sides",				//sides, inside: position of the arrows, used on compact type			
21926			lightbox_arrows_offset: 10,						//The horizontal offset of the arrows
21927			lightbox_arrows_inside_offset: 10,				//The offset from the image border if the arrows placed inside
21928			lightbox_arrows_inside_alwayson: false,			//Show the arrows on mouseover, or always on.
21929			
21930			lightbox_overlay_color:null,					//the color of the overlay. if null - will take from css
21931			lightbox_overlay_opacity:1,						//the opacity of the overlay. if null - will take from css
21932			lightbox_top_panel_opacity: null,				//the opacity of the top panel
21933			
21934			lightbox_show_numbers: true,					//show numbers on the right side
21935			lightbox_numbers_size: null,					//the size of the numbers string
21936			lightbox_numbers_color: null,					//the color of the numbers
21937			lightbox_numbers_padding_top:null,				//the top padding of the numbers (used in compact mode)
21938			lightbox_numbers_padding_right:null,			//the right padding of the numbers (used in compact mode)
21939			
21940			lightbox_compact_closebutton_offsetx: 1,		//the offsetx of the close button. Valid only for compact mode
21941			lightbox_compact_closebutton_offsety: 1,		//the offsetx of the close button. Valid only for compact mode
21942			
21943			lightbox_close_on_emptyspace:true				//close the lightbox on empty space
21944	};
21945	
21946	this.events = {
21947			LIGHTBOX_INIT: "lightbox_init"
21948	};
21949	
21950	var g_temp = {
21951			topPanelHeight: 44,
21952			initTextPanelHeight: 26,		//init height for compact mode
21953			isOpened: false, 
21954			isRightNowOpened:false,
21955			putSlider: true,
21956			isCompact: false,
21957			fadeDuration: 300,
21958			positionFrom: null,
21959			textPanelTop: null,
21960			textPanelLeft: null,
21961			isArrowsInside: false,
21962			isArrowsOnHoverMode: false,
21963			lastMouseX: null,
21964			lastMouseY: null,
21965			originalOptions: null,
21966			isSliderChangedOnce:false,
21967			isTopPanelEnabled:true
21968	};
21969	
21970	var g_defaults = {
21971			lightbox_slider_controls_always_on: true,
21972			lightbox_slider_enable_bullets: false,
21973			lightbox_slider_enable_arrows: false,
21974			lightbox_slider_enable_progress_indicator: false,
21975			lightbox_slider_enable_play_button: false,
21976			lightbox_slider_enable_fullscreen_button: false,
21977			lightbox_slider_enable_zoom_panel: false,
21978			lightbox_slider_enable_text_panel: false,
21979			lightbox_slider_scale_mode_media: "down",
21980			lightbox_slider_scale_mode: "down",
21981			lightbox_slider_loader_type: 3,
21982			lightbox_slider_loader_color: "black",
21983			lightbox_slider_transition: "fade",
21984			
21985			lightbox_slider_image_padding_top: g_temp.topPanelHeight,
21986			lightbox_slider_image_padding_bottom: 0,
21987			
21988			lightbox_slider_video_padding_top: 0,
21989			lightbox_slider_video_padding_bottom: 0,
21990			
21991			lightbox_textpanel_align: "middle",
21992			lightbox_textpanel_padding_top: 5,
21993			lightbox_textpanel_padding_bottom: 5,
21994			
21995			slider_video_constantsize: false,
21996			lightbox_slider_image_border: false,
21997			
21998			lightbox_textpanel_enable_title: true,
21999			lightbox_textpanel_enable_description: false,
22000			lightbox_textpanel_desc_style_as_title: true,
22001			
22002			lightbox_textpanel_enable_bg:false,
22003			
22004			video_enable_closebutton: false,
22005			lightbox_slider_video_enable_closebutton: false,
22006			video_youtube_showinfo: false,
22007			lightbox_slider_enable_links:false
22008	};
22009	
22010	var g_defaultsCompact = {
22011			lightbox_overlay_opacity:0.6,
22012			
22013			lightbox_slider_image_border: true,
22014			lightbox_slider_image_shadow:true,
22015			lightbox_slider_image_padding_top: 30,
22016			lightbox_slider_image_padding_bottom: 30,
22017			
22018			slider_video_constantsize: true,
22019						
22020			lightbox_textpanel_align: "bottom",
22021			lightbox_textpanel_title_text_align: "left",
22022			lightbox_textpanel_desc_text_align: "left",
22023			lightbox_textpanel_padding_left: 10,			//the padding left of the textpanel
22024			lightbox_textpanel_padding_right: 10
22025	};
22026	
22027	
22028	function __________GENERAL_________(){};
22029	
22030	
22031	/**
22032	 * init the gallery
22033	 */
22034	function initLightbox(gallery, customOptions){
22035		
22036		g_gallery = gallery;
22037		g_objGallery = jQuery(gallery);
22038		
22039		g_options = jQuery.extend(g_options, g_defaults);
22040		g_options = jQuery.extend(g_options, customOptions);
22041		
22042		g_temp.originalOptions = jQuery.extend({}, g_options);
22043		
22044		if(g_options.lightbox_type == "compact"){
22045			g_temp.isCompact = true;
22046			g_options = jQuery.extend(g_options, g_defaultsCompact);
22047			g_options = jQuery.extend(g_options, customOptions);
22048		}
22049		
22050		//modify some options
22051		modifyOptions();
22052		
22053		if(g_temp.putSlider == true){
22054			
22055			g_gallery.initSlider(g_options, "lightbox");
22056			g_objects = gallery.getObjects();
22057			g_objSlider = g_objects.g_objSlider;			
22058			
22059		}else{
22060			g_objSlider = null;
22061		}
22062		
22063		if(g_options.lightbox_show_textpanel == true){
22064			g_objTextPanel.init(g_gallery, g_options, "lightbox");
22065		}
22066		else
22067			g_objTextPanel = null;
22068		
22069		
22070	}
22071	
22072	
22073	/**
22074	 * modify some options according user options
22075	 */
22076	function modifyOptions(){
22077		
22078		if(g_temp.isCompact == true && g_options.lightbox_show_textpanel == true){
22079			g_options.lightbox_slider_image_padding_bottom = g_temp.initTextPanelHeight;
22080		}
22081		
22082		if(g_temp.isCompact == true && g_options.lightbox_arrows_position == "inside"){
22083			g_temp.isArrowsInside = true;
22084		}
22085
22086		if(g_temp.isArrowsInside == true && g_options.lightbox_arrows_inside_alwayson == false)
22087			g_temp.isArrowsOnHoverMode = true;
22088		
22089		//disable top panel if no text panel enabled
22090		if(g_options.lightbox_show_textpanel == false){
22091			g_temp.isTopPanelEnabled = false;
22092			g_temp.topPanelHeight = 0;
22093			g_options.lightbox_slider_image_padding_top = 0;
22094		}
22095		
22096		//modify slider image border width
22097		
22098		
22099	}
22100	
22101	
22102	/**
22103	 * put the lightbox html
22104	 */
22105	function putLightboxHtml(){
22106		
22107		var html = "";
22108		var classAddition = "";
22109		if(g_temp.isCompact == true){
22110			classAddition = " ug-lightbox-compact";
22111		}
22112		
22113		html += "<div class='ug-gallery-wrapper ug-lightbox"+classAddition+"'>";
22114		html += "<div class='ug-lightbox-overlay'></div>";
22115		
22116		//set top panel only on wide mode
22117		if(g_temp.isCompact == false && g_temp.isTopPanelEnabled){
22118			html += "<div class='ug-lightbox-top-panel'>";
22119			html += 	"<div class='ug-lightbox-top-panel-overlay'></div>";
22120			
22121			if(g_options.lightbox_show_numbers)
22122				html += 	"<div class='ug-lightbox-numbers'></div>";
22123			
22124			html += "</div>";	//top panel
22125		}else{
22126			
22127			//put numbers without top panel
22128			if(g_options.lightbox_show_numbers)
22129				html += 	"<div class='ug-lightbox-numbers'></div>";
22130			
22131		}
22132		
22133		
22134		html += 	"<div class='ug-lightbox-button-close'></div>";
22135		
22136		html += "<div class='ug-lightbox-arrow-left'></div>";		
22137		html += "<div class='ug-lightbox-arrow-right'></div>";
22138		
22139		html += "</div>";
22140		
22141		g_objWrapper = jQuery(html);
22142		
22143		jQuery("body").append(g_objWrapper);
22144		
22145		if(g_objSlider)
22146			g_objSlider.setHtml(g_objWrapper);
22147		
22148		g_objOverlay = g_objWrapper.children(".ug-lightbox-overlay");
22149		
22150		if(g_temp.isCompact == false && g_temp.isTopPanelEnabled == true){
22151			g_objTopPanel = g_objWrapper.children(".ug-lightbox-top-panel");
22152			if(g_objTopPanel.length == 0)
22153				g_objTopPanel = null;
22154		}
22155		
22156		g_objButtonClose = g_objWrapper.find(".ug-lightbox-button-close");
22157		
22158		if(g_options.lightbox_show_numbers)
22159			g_objNumbers = g_objWrapper.find(".ug-lightbox-numbers");
22160		
22161		g_objArrowLeft = g_objWrapper.children(".ug-lightbox-arrow-left");
22162		g_objArrowRight = g_objWrapper.children(".ug-lightbox-arrow-right");
22163				
22164		if(g_objTextPanel){
22165			if(g_objTopPanel)
22166				g_objTextPanel.appendHTML(g_objTopPanel);
22167			else
22168				g_objTextPanel.appendHTML(g_objWrapper);
22169		}
22170
22171	}
22172	
22173	
22174	/**
22175	 * set lightbox properties
22176	 */
22177	function setProperties(){
22178		
22179		if(g_options.lightbox_overlay_color !== null)
22180			g_objOverlay.css("background-color", g_options.lightbox_overlay_color);
22181		
22182		if(g_options.lightbox_overlay_opacity !== null)
22183			g_objOverlay.fadeTo(0, g_options.lightbox_overlay_opacity);
22184		
22185		if(g_objTopPanel && g_options.lightbox_top_panel_opacity !== null){
22186			g_objTopPanel.children(".ug-lightbox-top-panel-overlay").fadeTo(0, g_options.lightbox_top_panel_opacity);
22187		}
22188			
22189		//set numbers properties
22190		if(g_objNumbers){
22191			var cssNumbers = {};
22192			
22193			if(g_options.lightbox_numbers_size !== null)
22194				cssNumbers["font-size"] = g_options.lightbox_numbers_size+"px";
22195			
22196			if(g_options.lightbox_numbers_color)
22197				cssNumbers["color"] = g_options.lightbox_numbers_color;
22198			
22199			if(g_options.lightbox_numbers_padding_right !== null)
22200				cssNumbers["padding-right"] = g_options.lightbox_numbers_padding_right + "px";
22201			
22202			if(g_options.lightbox_numbers_padding_top !== null)
22203				cssNumbers["padding-top"] = g_options.lightbox_numbers_padding_top + "px";
22204			
22205			
22206			g_objNumbers.css(cssNumbers);
22207		}
22208		
22209	}
22210	
22211	
22212	/**
22213	 * refresh slider item with new height
22214	 */
22215	function refreshSliderItem(newHeight){
22216		
22217		if(!g_objSlider)
22218			return(true);
22219				
22220		//set slider new image position
22221		var objOptions = {
22222				slider_image_padding_top: newHeight
22223		};
22224		
22225		g_objSlider.setOptions(objOptions);
22226		g_objSlider.refreshSlideItems();
22227	
22228	}
22229	
22230	function __________WIDE_ONLY_________(){};
22231	
22232	
22233	/**
22234	 * handle panel height according text height
22235	 */
22236	function handlePanelHeight(fromWhere){
22237		
22238		if(!g_objTopPanel)
22239			return(false);
22240			
22241		if(!g_objTextPanel)
22242			return(false);
22243		
22244		//check text panel size, get the panel bigger then
22245		var panelHeight = g_objTopPanel.height();
22246		if(panelHeight == 0)
22247			return(false);
22248		
22249		if(g_objTopPanel.is(":visible") == false)
22250			return(false);
22251		
22252		var newPanelHeight = panelHeight;
22253		
22254		var objTextPanelSize = g_objTextPanel.getSize();
22255		
22256		var textPanelHeight = objTextPanelSize.height;
22257		
22258		if(panelHeight != g_temp.topPanelHeight)
22259			newPanelHeight = g_temp.topPanelHeight;
22260				
22261		if(textPanelHeight > newPanelHeight)
22262			newPanelHeight = textPanelHeight;
22263				
22264		if(panelHeight != newPanelHeight){
22265			g_objTopPanel.height(newPanelHeight);
22266			
22267			if(g_objSlider && g_objSlider.isAnimating() == false)
22268				refreshSliderItem(newPanelHeight);
22269		}
22270				
22271	}
22272
22273
22274	/**
22275	 * position text panel for wide
22276	 * size - wrapper size
22277	 */
22278	function positionTextPanelWide(size){
22279
22280		var objOptions = {};
22281		
22282		var textWidth = g_options.lightbox_textpanel_width;
22283		var minPaddingLeft = 47;
22284		var minPaddingRight = 40;
22285		var maxTextPanelWidth = size.width - minPaddingLeft - minPaddingRight;
22286		
22287		if(textWidth > maxTextPanelWidth){		//mobile mode
22288			
22289			objOptions.textpanel_padding_left = minPaddingLeft;
22290			objOptions.textpanel_padding_right = minPaddingRight;
22291			
22292			objOptions.textpanel_title_text_align = "center";
22293			objOptions.textpanel_desc_text_align = "center";			
22294		}else{
22295			objOptions.textpanel_padding_left = Math.floor((size.width - textWidth) / 2);
22296			objOptions.textpanel_padding_right = objOptions.textpanel_padding_left;
22297			objOptions.textpanel_title_text_align = "left";
22298			objOptions.textpanel_desc_text_align = "left";
22299			
22300			if(g_options.lightbox_textpanel_title_text_align)
22301					objOptions.textpanel_title_text_align = g_options.lightbox_textpanel_desc_text_align;
22302			
22303			if(g_options.lightbox_textpanel_desc_text_align)
22304				objOptions.textpanel_desc_text_align = g_options.lightbox_textpanel_desc_text_align;
22305			
22306		}
22307				
22308		g_objTextPanel.setOptions(objOptions);
22309		
22310		g_objTextPanel.refresh(true, true);
22311		
22312		handlePanelHeight("positionTextPanelWide");
22313		g_objTextPanel.positionPanel();
22314	}
22315	
22316	/**
22317	 * hide top panel
22318	 */
22319	function hideTopPanel(){
22320				
22321		if(!g_objTopPanel)
22322			return(false);
22323		
22324		g_objTopPanel.hide();
22325	}
22326	
22327	
22328	/**
22329	 * show top panel
22330	 */
22331	function showTopPanel(){
22332		
22333		if(!g_objTopPanel)
22334			return(false);
22335		
22336		g_objTopPanel.show();
22337	}
22338	
22339	
22340	function __________COMPACT_ONLY_________(){};
22341
22342	/**
22343	 * handle slider image height according the textpanel height
22344	 * refresh the slider if the height is not in place
22345	 */
22346	function handleCompactHeight(objImageSize){
22347				
22348		if(g_temp.isOpened == false)
22349			return(false);
22350		
22351		if(!g_objTextPanel)
22352			return(false);
22353		
22354		if(!g_objSlider)
22355			return(false);
22356		
22357		var wrapperSize = g_functions.getElementSize(g_objWrapper);
22358		var textPanelSize = g_objTextPanel.getSize();
22359		
22360		if(textPanelSize.width == 0 || textPanelSize.height > 120)
22361			return(false);
22362		
22363		if(!objImageSize){
22364			var objImage = g_objSlider.getSlideImage();
22365			var objImageSize = g_functions.getElementSize(objImage);
22366		}
22367		
22368		if(objImageSize.height == 0 || objImageSize.width == 0)
22369			return(false);
22370		
22371		//check elements end size
22372		var totalBottom = objImageSize.bottom + textPanelSize.height;
22373		
22374		if(totalBottom < wrapperSize.height)
22375			return(false);
22376		
22377		var sliderOptions = g_objSlider.getOptions();
22378		
22379		var imagePaddingBottom = textPanelSize.height;
22380		
22381		if(imagePaddingBottom != sliderOptions.slider_image_padding_bottom){
22382			
22383			var objOptions = {
22384					slider_image_padding_bottom: imagePaddingBottom
22385			};
22386			
22387			if(g_objSlider.isAnimating() == false){
22388				g_objSlider.setOptions(objOptions);
22389				g_objSlider.refreshSlideItems();
22390				return(true);
22391			}
22392			
22393		}
22394		
22395		return(false);
22396	}
22397	
22398	/**
22399	 * set text panel top of compact mode
22400	 */
22401	function setCompactTextpanelTop(objImageSize, positionPanel){
22402		
22403		if(!objImageSize){
22404			var objImage = g_objSlider.getSlideImage();
22405			var objImageSize = g_functions.getElementSize(objImage);
22406		}
22407		
22408		g_temp.textPanelTop = objImageSize.bottom;
22409		
22410		if(positionPanel === true)
22411			g_objTextPanel.positionPanel(g_temp.textPanelTop, g_temp.textPanelLeft);
22412	}
22413	
22414	
22415	/**
22416	 * handle text panel width on compact mode, 
22417	 * run when the image is ready. 
22418	 * Set top position of the panel as well
22419	 * position numbers as well
22420	 */
22421	function handleCompactTextpanelSizes(showTextpanel){
22422			
22423		var wrapperSize = g_functions.getElementSize(g_objWrapper);
22424		var objImage = g_objSlider.getSlideImage();
22425		var objImageSize = g_functions.getElementSize(objImage);
22426		
22427		if(objImageSize.width == 0)
22428			return(false);
22429		
22430		
22431		g_temp.textPanelLeft = objImageSize.left;
22432		g_temp.textPanelTop = objImageSize.bottom;
22433
22434		var textPanelWidth = objImageSize.width;
22435		
22436		if(g_objNumbers){
22437			
22438			var objNumbersSize = g_functions.getElementSize(g_objNumbers);
22439			textPanelWidth -= objNumbersSize.width;
22440			
22441			//place numbers object
22442			var numbersLeft = objImageSize.right - objNumbersSize.width;
22443			g_functions.placeElement(g_objNumbers, numbersLeft, g_temp.textPanelTop);
22444		}
22445			
22446			
22447		if(g_objTextPanel){
22448			g_objTextPanel.show();
22449			g_objTextPanel.refresh(true, true, textPanelWidth);
22450			setCompactTextpanelTop(objImageSize);
22451		}
22452		
22453		var isChanged = handleCompactHeight(objImageSize);
22454		
22455		if(isChanged == false){
22456			
22457			g_temp.positionFrom = "handleCompactTextpanelSizes";
22458			
22459			if(g_objTextPanel){
22460				g_objTextPanel.positionPanel(g_temp.textPanelTop, g_temp.textPanelLeft);
22461				if(showTextpanel === true){
22462					showTextpanel();
22463					showNumbers();
22464				}
22465			}
22466			
22467		}
22468		
22469	}
22470	
22471	
22472	
22473	/**
22474	 * return that current slider image is in place
22475	 */
22476	function isSliderImageInPlace(){
22477
22478		if(g_objSlider.isCurrentSlideType("image") == false)
22479			return(true);
22480		
22481		var isImageInPlace = (g_objSlider.isCurrentImageInPlace() == true);
22482				
22483		return(isImageInPlace);
22484	}
22485	
22486	
22487	/**
22488	 * position the arrows inside mode
22489	 */
22490	function positionArrowsInside(toShow, isAnimation){
22491				
22492		if(g_temp.isArrowsInside == false)
22493			return(false);
22494		
22495		if(!g_objArrowLeft)
22496			return(false);
22497		
22498		var isImageInPlace = isSliderImageInPlace();
22499		
22500		g_objArrowLeft.show();
22501		g_objArrowRight.show();
22502		
22503		g_temp.positionFrom = "positionArrowsInside";
22504		
22505		if(g_temp.isArrowsOnHoverMode == true && isImageInPlace == true && isMouseInsideImage() == false)
22506			hideArrows(true);
22507		
22508		if(isImageInPlace == false){
22509			var leftArrowLeft = g_functions.getElementRelativePos(g_objArrowLeft, "left", g_options.lightbox_arrows_offset);
22510			var leftArrowTop = g_functions.getElementRelativePos(g_objArrowLeft, "middle");
22511						
22512			var rightArrowLeft = g_functions.getElementRelativePos(g_objArrowRight, "right", g_options.lightbox_arrows_offset);
22513			var rightArrowTop = leftArrowTop;
22514
22515		}else{
22516			
22517			var objImage = g_objSlider.getSlideImage();
22518			var objImageSize = g_functions.getElementSize(objImage);
22519			var objSliderSize = g_functions.getElementSize(g_objSlider.getElement());
22520						
22521			var leftArrowLeft = g_functions.getElementRelativePos(g_objArrowLeft, "left", 0, objImage) + objImageSize.left + g_options.lightbox_arrows_inside_offset;
22522			var leftArrowTop = g_functions.getElementRelativePos(g_objArrowLeft, "middle", 0, objImage) + objImageSize.top;
22523			var rightArrowLeft = g_functions.getElementRelativePos(g_objArrowLeft, "right", 0, objImage) + objImageSize.left - g_options.lightbox_arrows_inside_offset;
22524			var rightArrowTop = leftArrowTop;
22525			
22526		}
22527		
22528		
22529		//place the image with animation or not
22530		if(isAnimation === true){
22531
22532			var objCssLeft = {
22533					left: leftArrowLeft,
22534					top: leftArrowTop
22535			};
22536			
22537			var objCssRight = {
22538					left: rightArrowLeft,
22539					top: rightArrowTop
22540			};
22541			
22542			g_objArrowLeft.stop().animate(objCssLeft,{
22543				duration: g_temp.fadeDuration
22544			});
22545			
22546			g_objArrowRight.stop().animate(objCssRight,{
22547				duration: g_temp.fadeDuration
22548			});
22549			
22550			
22551		}else{
22552			g_objArrowLeft.stop();
22553			g_objArrowRight.stop();
22554			
22555			g_functions.placeElement(g_objArrowLeft, leftArrowLeft, leftArrowTop);
22556			g_functions.placeElement(g_objArrowRight, rightArrowLeft, rightArrowTop);
22557		}
22558		
22559		
22560		if(toShow == true)
22561			showArrows(isAnimation);
22562		
22563	}
22564	
22565	
22566	
22567	/**
22568	 * position close button for compact type
22569	 */
22570	function positionCloseButton(toShow, isAnimation){
22571		
22572		g_temp.positionFrom = null;
22573		
22574		var isImageInPlace = isSliderImageInPlace();
22575		
22576		var minButtonTop = 2;
22577		var maxButtonLeft = g_functions.getElementRelativePos(g_objButtonClose, "right", 2, g_objWrapper);
22578		
22579		if(isImageInPlace == false){	//put image to corner
22580			
22581			var closeButtonTop = minButtonTop;
22582			var closeButtonLeft = maxButtonLeft;
22583			
22584		}else{
22585			var objImage = g_objSlider.getSlideImage();
22586			var objImageSize = g_functions.getElementSize(objImage);
22587			var objSliderSize = g_functions.getElementSize(g_objSlider.getElement());
22588			var objButtonSize = g_functions.getElementSize(g_objButtonClose);
22589			
22590			//some strange bug
22591			if(objSliderSize.top == objSliderSize.height)	
22592				objSliderSize.top = 0;
22593			
22594			var closeButtonLeft = objSliderSize.left + objImageSize.right - objButtonSize.width / 2 + g_options.lightbox_compact_closebutton_offsetx;
22595			var closeButtonTop = objSliderSize.top + objImageSize.top - objButtonSize.height / 2 - g_options.lightbox_compact_closebutton_offsety;
22596			
22597			if(closeButtonTop < minButtonTop)
22598				closeButtonTop = minButtonTop;
22599			
22600			if(closeButtonLeft > maxButtonLeft)
22601				closeButtonLeft = maxButtonLeft;
22602			
22603		}
22604		
22605		//place the image with animation or not
22606		if(isAnimation === true){
22607			var objCss = {
22608					left: closeButtonLeft,
22609					top: closeButtonTop
22610			};
22611			
22612			g_objButtonClose.stop().animate(objCss,{
22613				duration: g_temp.fadeDuration
22614			});
22615			
22616		}else{
22617			g_objButtonClose.stop();
22618			g_functions.placeElement(g_objButtonClose, closeButtonLeft, closeButtonTop);
22619		}
22620		
22621		if(toShow === true)
22622			showCloseButton(isAnimation);
22623		
22624	}
22625	
22626	
22627	/**
22628	 * hide close button
22629	 */
22630	function hideCompactElements(){
22631		
22632		if(g_objButtonClose)
22633			g_objButtonClose.stop().fadeTo(g_temp.fadeDuration, 0);
22634		
22635		hideTextPanel();
22636		
22637		hideNumbers();
22638		
22639		g_temp.positionFrom = "hideCompactElements";
22640		if(g_temp.isArrowsInside == true)
22641			hideArrows();
22642	}
22643
22644	
22645	/**
22646	 * actual hide all compact type elements
22647	 */
22648	function actualHideCompactElements(){
22649		
22650		if(g_objButtonClose)
22651			g_objButtonClose.hide();
22652		
22653		if(g_objArrowLeft && g_temp.isArrowsInside == true){
22654			g_objArrowLeft.hide();
22655			g_objArrowRight.hide();
22656		}
22657		
22658		if(g_objNumbers)
22659			g_objNumbers.hide();
22660		
22661		if(g_objTextPanel)
22662			g_objTextPanel.hide();
22663		
22664	}
22665	
22666	
22667	function __________COMMON_________(){};
22668	
22669	
22670	/**
22671	 * position the elements
22672	 */
22673	function positionElements(){
22674						
22675		var size = g_functions.getElementSize(g_objWrapper);
22676		
22677		//position top panel:
22678		if(g_objTopPanel)
22679			g_functions.setElementSizeAndPosition(g_objTopPanel, 0, 0, size.width, g_temp.topPanelHeight);
22680		
22681		//position arrows
22682		if(g_objArrowLeft && g_temp.isArrowsInside == false){
22683			
22684			if(g_options.lightbox_hide_arrows_onvideoplay == true){
22685				g_objArrowLeft.show();
22686				g_objArrowRight.show();
22687			}
22688			
22689			g_functions.placeElement(g_objArrowLeft, "left", "middle", g_options.lightbox_arrows_offset);
22690			g_functions.placeElement(g_objArrowRight, "right", "middle", g_options.lightbox_arrows_offset);
22691		}		
22692		
22693		if(g_temp.isCompact == false)
22694			g_functions.placeElement(g_objButtonClose, "right", "top", 2, 2);
22695		
22696		//place text panel
22697		if(g_objTextPanel){
22698			
22699			g_temp.positionFrom = "positionElements";
22700			
22701			if(g_temp.isCompact == false)
22702				positionTextPanelWide(size);
22703			else{
22704				showTextPanel();
22705				showNumbers();
22706			}
22707			
22708		}
22709		
22710		var sliderWidth = size.width;
22711		var sliderHeight = size.height;	
22712		var sliderTop = 0;
22713		var sliderLeft = 0;
22714		
22715		if(g_objSlider){
22716			
22717			if(g_objTopPanel){
22718				var topPanelHeight = g_objTopPanel.height();
22719				var objOptions = {
22720						slider_image_padding_top: topPanelHeight
22721				};
22722				g_objSlider.setOptions(objOptions);
22723			}
22724			
22725			g_objSlider.setSize(sliderWidth, sliderHeight);
22726			g_objSlider.setPosition(sliderLeft, sliderTop);
22727		}
22728		
22729	}
22730	
22731	
22732	/**
22733	 * hide the text panel
22734	 */
22735	function hideTextPanel(){
22736		
22737		if(g_objTextPanel)
22738			g_objTextPanel.getElement().stop().fadeTo(g_temp.fadeDuration, 0);
22739		
22740	}
22741	
22742	
22743	/**
22744	 * hide the numbers text
22745	 */
22746	function hideNumbers(){
22747		
22748		if(g_objNumbers)
22749			g_objNumbers.stop().fadeTo(g_temp.fadeDuration, 0);
22750	}
22751	
22752	
22753	/**
22754	 * is mouse inside image
22755	 */
22756	function isMouseInsideImage(){
22757		if(!g_temp.lastMouseX)
22758			return(true);
22759		var obj = {
22760				pageX: g_temp.lastMouseX, 
22761				pageY: g_temp.lastMouseY
22762			};
22763	
22764		var isMouseInside = g_objSlider.isMouseInsideSlideImage(obj);
22765		
22766		return(isMouseInside);
22767	}
22768	
22769	
22770	/**
22771	 * hide the arrows
22772	 */
22773	function hideArrows(noAnimation, isForce){
22774		
22775		if(!g_objArrowLeft)
22776			return(false);
22777				
22778		//don't hide the arrows if mouse inside image
22779		if(g_temp.isArrowsOnHoverMode == true && isForce === false){
22780			if(isMouseInsideImage() == true);
22781				return(true);
22782		}
22783		
22784		if(noAnimation === true){
22785			g_objArrowLeft.stop().fadeTo(0, 0);
22786			g_objArrowRight.stop().fadeTo(0, 0);
22787		}else{
22788			g_objArrowLeft.stop().fadeTo(g_temp.fadeDuration, 0);
22789			g_objArrowRight.stop().fadeTo(g_temp.fadeDuration, 0);
22790		}
22791				
22792	}
22793	
22794	/**
22795	 * get if the arrows are hidden
22796	 */
22797	function isArrowsHidden(){
22798		
22799		if(!g_objArrowLeft)
22800			return(true);
22801		if(g_objArrowLeft.is(":visible") == false)
22802			return(true);
22803		
22804		var opacity = g_objArrowLeft.css("opacity");
22805		if(opacity != 1)
22806			return(true);
22807		
22808		return(false);
22809	}
22810	
22811	/**
22812	 * show the arrows
22813	 */
22814	function showArrows(noStop, fromHover){
22815		
22816		if(!g_objArrowLeft)
22817			return(false);
22818		
22819		//don't show every time on arrowsonhover mode
22820		if(g_temp.isArrowsOnHoverMode == true && fromHover !== true && isSli
22820derImageInPlace() == true)
22821			return(true);
22822		
22823		//don't show if swiping
22824		if(g_objSlider.isSwiping() == true)
22825			return(true);
22826			
22827		if(noStop !== true){
22828			g_objArrowLeft.stop();
22829			g_objArrowRight.stop();
22830		}
22831		
22832		g_objArrowLeft.fadeTo(g_temp.fadeDuration, 1);
22833		g_objArrowRight.fadeTo(g_temp.fadeDuration, 1);
22834		
22835	}
22836
22837	
22838	
22839	
22840	
22841	/**
22842	 * show close button
22843	 */
22844	function showCloseButton(noStop){
22845		
22846		if(noStop !== true)
22847			g_objButtonClose.stop();
22848		
22849		g_objButtonClose.fadeTo(g_temp.fadeDuration, 1);
22850	}
22851	
22852	
22853	/**
22854	 * update text panel text of the curren item
22855	 */
22856	function updateTextPanelText(currentItem){
22857		
22858		if(!g_objTextPanel)
22859			return(false);
22860		
22861		if(!currentItem)
22862			var currentItem = g_objSlider.getCurrentItem();
22863		
22864		g_objTextPanel.setTextPlain(currentItem.title, currentItem.description);
22865	}
22866
22867	
22868	/**
22869	 * update numbers text
22870	 */
22871	function updateNumbersText(currentItem){
22872		
22873		if(!g_objNumbers)
22874			return(false);
22875		
22876		if(!currentItem)
22877			var currentItem = g_objSlider.getCurrentItem();
22878		
22879		var numItems = g_gallery.getNumItems();
22880		var numCurrentItem = currentItem.index + 1;
22881		g_objNumbers.html(numCurrentItem + " / " + numItems);
22882	}
22883	
22884	
22885	/**
22886	 * show the text panel
22887	 */
22888	function showTextPanel(){
22889		
22890		if(!g_objTextPanel)
22891			return(false);
22892		
22893		g_objTextPanel.getElement().show().stop().fadeTo(g_temp.fadeDuration, 1);
22894		
22895	}
22896
22897	
22898	/**
22899	 * Show the numbers object
22900	 */
22901	function showNumbers(){
22902		
22903		if(g_objNumbers)
22904			g_objNumbers.stop().fadeTo(g_temp.fadeDuration, 1);
22905	}
22906	
22907	
22908	function __________EVENTS_________(){};
22909	
22910	
22911	/**
22912	 * on start dragging slider item event. hide the elements
22913	 */
22914	function onSliderDragStart(){
22915		if(g_temp.isCompact == false)
22916			return(true);
22917		
22918		hideCompactElements();
22919	}
22920
22921	
22922	/**
22923	 * on zoom change
22924	 * move the assets of compact to their places
22925	 */
22926	function onZoomChange(){
22927		if(g_temp.isCompact == false)
22928			return(true);
22929		
22930		g_temp.positionFrom = "onZoomChange";
22931	
22932		positionCloseButton(false, true);
22933		positionArrowsInside(false, true);
22934		
22935		//handle compact text panel mode
22936		if(g_temp.isCompact == true){
22937			var isImageInPlace = (g_objSlider.isCurrentSlideType("image") && g_objSlider.isCurrentImageInPlace() == true);
22938			if(isImageInPlace == false){
22939				hideTextPanel();
22940				hideNumbers();
22941			}
22942			else{
22943				g_temp.positionFrom = "onZoomChange";
22944				showTextPanel();
22945				showNumbers();
22946			}
22947		}
22948		
22949	}
22950	
22951
22952	/**
22953	 * after return slider to it's place
22954	 * show close button
22955	 */
22956	function onSliderAfterReturn(){
22957		
22958		if(g_temp.isCompact == false)
22959			return(true);
22960		
22961		g_temp.positionFrom = "onSliderAfterReturn";
22962		
22963		positionCloseButton(true);
22964		positionArrowsInside(true);
22965		
22966		var isChanged = handleCompactHeight();
22967		if(isChanged == false)
22968			handleCompactTextpanelSizes();
22969		
22970		showTextPanel();
22971		showNumbers();
22972	}
22973	
22974	
22975	/**
22976	 * after put image to the slide
22977	 * position compact elements
22978	 */
22979	function onSliderAfterPutImage(data, objSlide){
22980				
22981		objSlide = jQuery(objSlide);
22982				
22983		if(g_temp.isCompact == false)
22984			return(true);
22985
22986		if(g_objSlider.isSlideCurrent(objSlide) == false)
22987			return(true);
22988				
22989		g_temp.positionFrom = "onSliderAfterPutImage";
22990		
22991		positionCloseButton(true);
22992		
22993		positionArrowsInside(true);
22994		
22995		handleCompactTextpanelSizes();
22996	}
22997	
22998	
22999	/**
23000	 * on slider transition end, handle panel height
23001	 */
23002	function onSliderTransitionEnd(){
23003		
23004		var sliderOptions = g_objSlider.getOptions();
23005		var imagePaddingTop = sliderOptions.slider_image_padding_top;
23006		
23007		//handle wide
23008		if(g_objTopPanel){
23009			var panelHeight = g_objTopPanel.height();
23010			
23011			if(panelHeight != imagePaddingTop)
23012				refreshSliderItem(panelHeight);
23013		}
23014		
23015		//handle compact
23016		if(g_temp.isCompact == true){
23017			
23018			updateTextPanelText();
23019			updateNumbersText();
23020			
23021			g_temp.positionFrom = "onSliderTransitionEnd";
23022			
23023			positionCloseButton(true);
23024			positionArrowsInside(true);
23025
23026			if(g_objSlider.isSlideActionActive() == false){
23027				var isChanged = handleCompactHeight();
23028				if(isChanged == false)
23029					handleCompactTextpanelSizes();
23030			}
23031			
23032			showTextPanel();
23033			showNumbers();
23034			
23035		}
23036		
23037	}
23038	
23039		
23040	/**
23041	 * on item change
23042	 * update numbers text and text panel text/position
23043	 */
23044	function onItemChange(data, currentItem){
23045		
23046		if(g_temp.isCompact == false){	//wide mode
23047			
23048			if(g_objNumbers)
23049				updateNumbersText(currentItem);
23050			
23051			if(g_objTextPanel){
23052				updateTextPanelText(currentItem);
23053				
23054				//update panel height only if the lightbox is already opened, and the items changed within it.
23055				if(g_temp.isRightNowOpened == false){
23056					g_objTextPanel.positionElements(false);
23057					handlePanelHeight("onchange");
23058					g_objTextPanel.positionPanel();
23059				}
23060				
23061			}
23062			
23063		}else{
23064			
23065			if(g_objSlider.isAnimating() == false){
23066				
23067				if(g_objTextPanel)
23068					updateTextPanelText(currentItem);
23069				
23070				if(g_objNumbers)
23071					updateNumbersText(currentItem);
23072			}
23073		
23074		}
23075		
23076		
23077		//trigger lightbox init event
23078		if(g_temp.isSliderChangedOnce == false){
23079			g_temp.isSliderChangedOnce = true;
23080			g_objThis.trigger(t.events.LIGHTBOX_INIT);
23081		}
23082		
23083	}
23084	
23085	
23086	/**
23087	 * on slider click
23088	 */
23089	function onSliderClick(data, event){
23090		
23091		var slideType = g_objSlider.getSlideType();
23092		if(slideType != "image" && g_temp.isCompact == false && g_objSlider.isSlideActionActive() )
23093			return(true);
23094		
23095		var isPreloading = g_objSlider.isPreloading();
23096		if(isPreloading == true){
23097			t.close("slider");
23098			return(true);
23099		}
23100		
23101		//close the lightbox on empty space click
23102		if(g_options.lightbox_close_on_emptyspace == true){
23103			
23104			var isInside = g_objSlider.isMouseInsideSlideImage(event);
23105			
23106			if(isInside == false)
23107				t.close("slider_inside");
23108		}
23109		
23110	}
23111	
23112	
23113	/**
23114	 * on lightbox resize
23115	 */
23116	function onResize(){
23117		
23118		positionElements();
23119	}
23120	
23121	
23122	
23123	/**
23124	 * on start play - hide the side buttons
23125	 */
23126	function onPlayVideo(){
23127		
23128		if(g_objTopPanel){
23129			hideTopPanel();
23130		}else{
23131			if(g_objNumbers)
23132				g_objNumbers.hide();
23133		}
23134		
23135		if(g_objArrowLeft && g_options.lightbox_hide_arrows_onvideoplay == true){
23136			g_objArrowLeft.hide();			
23137			g_objArrowRight.hide();			
23138		}
23139		
23140	}
23141	
23142	
23143	/**
23144	 * on stop video - show the side buttons
23145	 */
23146	function onStopVideo(){
23147
23148		if(g_objTopPanel){
23149			showTopPanel();
23150			handlePanelHeight("onStopVideo");
23151		}else{
23152			
23153			if(g_objNumbers)
23154				g_objNumbers.show();
23155		}
23156		
23157		if(g_objArrowLeft && g_options.lightbox_hide_arrows_onvideoplay == true){
23158			g_objArrowLeft.show();
23159			g_objArrowRight.show();			
23160		}
23161		
23162	}
23163	
23164	/**
23165	 * on gallery keypres, do operations
23166	 */
23167	function onKeyPress(data, key, event){
23168		
23169		var isScrollKey = false;
23170		
23171		switch(key){
23172			case 27:		//escape - close lightbox
23173				if(g_temp.isOpened == true)
23174					t.close("keypress");
23175			break;
23176			case 38:	//up and down arrows
23177			case 40:
23178			case 33:	//page up and down
23179			case 34:
23180				isScrollKey = true;
23181			break;
23182		}
23183		
23184		if(g_temp.isOpened == true && isScrollKey == true)
23185			event.preventDefault();
23186		
23187		
23188	}
23189	
23190	/**
23191	 * on image mouse enter event
23192	 */
23193	function onImageMouseEnter(){
23194		
23195		if(g_temp.isArrowsOnHoverMode == true)
23196			showArrows(false, true);
23197		
23198	}
23199	
23200	/**
23201	 * on image mouse leave
23202	 */
23203	function onImageMouseLeave(event){
23204		
23205		g_temp.positionFrom = "hideCompactElements";
23206		
23207		if(g_temp.isArrowsOnHoverMode == true && isSliderImageInPlace() == true)
23208			hideArrows(false, true);
23209		
23210	}
23211	
23212	
23213	/**
23214	 * on mouse move event
23215	 * show arrows if inside image
23216	 */
23217	function onMouseMove(event){
23218		 g_temp.lastMouseX = event.pageX;
23219		 g_temp.lastMouseY = event.pageY;
23220		
23221		 var isHidden = isArrowsHidden()
23222		 
23223		 
23224		 if(isHidden == true && isMouseInsideImage() && g_objSlider.isAnimating() == false){
23225			 g_temp.positionFrom = "onMouseMove";
23226			 if(g_objArrowLeft && g_objArrowLeft.is(":animated") == false)
23227				 showArrows(false, true);
23228		 }
23229		 
23230	}
23231
23232	
23233	/**
23234	 * on mouse wheel
23235	 */
23236	function onMouseWheel(event, delta, deltaX, deltaY){
23237		
23238		if(g_temp.isOpened == false)
23239			return(true);
23240		
23241		switch(g_options.gallery_mousewheel_role){
23242			default:
23243			case "zoom":
23244				var slideType = g_objSlider.getSlideType();
23245				if(slideType != "image")
23246					event.preventDefault();
23247			break;
23248			case "none":
23249				event.preventDefault();
23250			break;
23251			case "advance":
23252				g_gallery.onGalleryMouseWheel(event, delta, deltaX, deltaY);
23253			break;
23254		}
23255		
23256	}
23257	
23258	
23259	/**
23260	 * init events
23261	 */
23262	function initEvents(){
23263		
23264		g_objOverlay.on("touchstart", function(event){
23265			event.preventDefault();
23266		});
23267		
23268		g_objOverlay.on("touchend", function(event){
23269			t.close("overlay");
23270		});
23271		
23272		
23273		g_functions.addClassOnHover(g_objArrowRight, "ug-arrow-hover");
23274		g_functions.addClassOnHover(g_objArrowLeft, "ug-arrow-hover");
23275		
23276		g_functions.addClassOnHover(g_objButtonClose);
23277		
23278		g_gallery.setNextButton(g_objArrowRight);
23279		g_gallery.setPrevButton(g_objArrowLeft);
23280		
23281		g_objButtonClose.click(function(){
23282			t.close("button");
23283		});
23284		
23285		g_objGallery.on(g_gallery.events.ITEM_CHANGE, onItemChange);
23286		
23287		if(g_objSlider){
23288			jQuery(g_objSlider).on(g_objSlider.events.TRANSITION_END, onSliderTransitionEnd);
23289			
23290			//on slider click event
23291			jQuery(g_objSlider).on(g_objSlider.events.CLICK, onSliderClick);
23292			
23293			//on slider video 
23294			var objVideo = g_objSlider.getVideoObject();
23295					
23296			jQuery(objVideo).on(objVideo.events.PLAY_START, onPlayVideo);
23297			jQuery(objVideo).on(objVideo.events.PLAY_STOP, onStopVideo);
23298			
23299			//handle close button hide / appear
23300			jQuery(g_objSlider).on(g_objSlider.events.START_DRAG, onSliderDragStart);
23301			jQuery(g_objSlider).on(g_objSlider.events.TRANSITION_START, onSliderDragStart);
23302			
23303			jQuery(g_objSlider).on(g_objSlider.events.AFTER_DRAG_CHANGE, onSliderAfterReturn);
23304			jQuery(g_objSlider).on(g_objSlider.events.AFTER_RETURN, onSliderAfterReturn);
23305			jQuery(g_objSlider).on(g_objSlider.events.AFTER_PUT_IMAGE, onSliderAfterPutImage);
23306			
23307			jQuery(g_objSlider).on(g_objSlider.events.ZOOM_CHANGE, onZoomChange);
23308			
23309			jQuery(g_objSlider).on(g_objSlider.events.IMAGE_MOUSEENTER, onImageMouseEnter);
23310			jQuery(g_objSlider).on(g_objSlider.events.IMAGE_MOUSELEAVE, onImageMouseLeave);
23311
23312		}
23313		
23314		//on resize
23315		 jQuery(window).resize(function(){
23316			 
23317			 if(g_temp.isOpened == false)
23318				 return(true);
23319			 
23320			 g_functions.whenContiniousEventOver("lightbox_resize", onResize, 100);
23321		 });
23322		 
23323		 g_objGallery.on(g_gallery.events.GALLERY_KEYPRESS, onKeyPress);
23324		 
23325		 //store last mouse x and y
23326		 if(g_temp.isArrowsOnHoverMode == true){
23327			 
23328			 jQuery(document).bind('mousemove', onMouseMove);
23329		 
23330		 }
23331		
23332		//on mouse wheel - disable functionality if video
23333		g_objWrapper.on("mousewheel", onMouseWheel);
23334
23335	}
23336
23337	
23338	/**
23339	 * destroy the lightbox events and the html it created
23340	 */
23341	this.destroy = function(){
23342		
23343		jQuery(document).unbind("mousemove");
23344		
23345		g_objOverlay.off("touchstart");
23346		g_objOverlay.off("touchend");
23347		g_objButtonClose.off("click");
23348		g_objGallery.off(g_gallery.events.ITEM_CHANGE);
23349		
23350		if(g_objSlider){
23351			jQuery(g_objSlider).off(g_objSlider.events.TRANSITION_END);
23352			jQuery(g_objSlider).off(g_objSlider.events.CLICK);
23353			jQuery(g_objSlider).off(g_objSlider.events.START_DRAG);
23354			jQuery(g_objSlider).off(g_objSlider.events.TRANSITION_START);
23355			jQuery(g_objSlider).off(g_objSlider.events.AFTER_DRAG_CHANGE);
23356			jQuery(g_objSlider).off(g_objSlider.events.AFTER_RETURN);
23357			
23358			var objVideo = g_objSlider.getVideoObject();
23359			jQuery(objVideo).off(objVideo.events.PLAY_START);
23360			jQuery(objVideo).off(objVideo.events.PLAY_STOP);
23361
23362			jQuery(g_objSlider).on(g_objSlider.events.IMAGE_MOUSEENTER, onImageMouseEnter);
23363			jQuery(g_objSlider).on(g_objSlider.events.IMAGE_MOUSELEAVE, onImageMouseLeave);
23364			
23365			g_objSlider.destroy();
23366		}
23367		
23368		jQuery(window).unbind("resize");
23369		g_objGallery.off(g_gallery.events.GALLERY_KEYPRESS, onKeyPress);
23370		
23371		g_objWrapper.off("mousewheel");
23372		
23373		//remove the html
23374		g_objWrapper.remove();
23375	}
23376	
23377	
23378	/**
23379	 * open the lightbox with some item index
23380	 */
23381	this.open = function(index){
23382		
23383		var objItem = g_gallery.getItem(index);
23384		
23385		g_temp.isOpened = true;
23386		
23387		//set if the panel right now opened
23388		g_temp.isRightNowOpened = true;
23389		setTimeout(function(){g_temp.isRightNowOpened = false},100);
23390		
23391		if(g_objSlider){
23392			g_objSlider.setItem(objItem, "lightbox_open");
23393		}
23394		
23395		if(g_objTextPanel){
23396			g_objTextPanel.setTextPlain(objItem.title, objItem.description);
23397		}
23398		
23399		g_objOverlay.stop().fadeTo(0,0);
23400		g_objWrapper.show();
23401		g_objWrapper.fadeTo(0,1);
23402		
23403		//show the overlay
23404		g_objOverlay.stop().fadeTo(g_temp.fadeDuration, g_options.lightbox_overlay_opacity);
23405		
23406		positionElements();
23407		
23408		if(g_temp.isCompact == true){
23409			
23410			var isPreloading = g_objSlider.isPreloading();
23411			if(isPreloading == true){
23412				
23413				actualHideCompactElements();
23414				
23415			}else{
23416				
23417				//hide only arrows if they are inside
23418				if(g_temp.isArrowsInside == true){
23419					g_objArrowLeft.hide();
23420					g_objArrowRight.hide();
23421				}
23422				
23423			}
23424				
23425		}
23426		
23427		if(g_objSlider)
23428			g_objSlider.startSlideAction();
23429		
23430		//trigger gallery event
23431		g_objGallery.trigger(g_gallery.events.OPEN_LIGHTBOX, objItem);
23432		
23433	}
23434	
23435	
23436	/**
23437	 * close the lightbox
23438	 */
23439	this.close = function(fromWhere){
23440				
23441		g_temp.isOpened = false;
23442		
23443		if(g_temp.isCompact == true)
23444			hideCompactElements();
23445		
23446		if(g_objSlider)
23447			g_objSlider.stopSlideAction();
23448		
23449		var slideType = g_objSlider.getSlideType();
23450				
23451		if(slideType != "image")
23452			g_objWrapper.hide();
23453		else{
23454			g_objWrapper.fadeTo(g_temp.fadeDuration,0,function(){
23455				g_objWrapper.hide();
23456			});
23457		}
23458
23459		g_objGallery.trigger(g_gallery.events.CLOSE_LIGHTBOX);
23460		
23461	}
23462	
23463	
23464	/**
23465	 * external init function
23466	 */
23467	this.init = function(gallery, customOptions){
23468		
23469		initLightbox(gallery, customOptions);
23470	}
23471	
23472	
23473	/**
23474	 * switch to wide mode from compact mode
23475	 */
23476	function switchToWide(){
23477		g_temp.isCompact = false;
23478		modifyOptions();
23479		
23480		g_temp.isArrowsInside = false;
23481		g_temp.isArrowsOnHoverMode = false;
23482	
23483		g_options = jQuery.extend({}, g_temp.originalOptions);
23484		
23485		g_options.lightbox_arrows_position = "sides";
23486		
23487		g_objSlider.setOptions(g_options);
23488	}
23489	
23490	
23491	/**
23492	 * external put html function
23493	 */
23494	this.putHtml = function(){
23495		
23496		//check if switch to wide mode
23497		var isSmallWindow = g_gallery.isSmallWindow();
23498		
23499		if(isSmallWindow && g_temp.isCompact == true)
23500			switchToWide();
23501		
23502		putLightboxHtml();
23503	}
23504	
23505	
23506	/**
23507	 * run lightbox elements
23508	 */
23509	this.run = function(){
23510		
23511		setProperties();
23512		
23513		if(g_objSlider)
23514			g_objSlider.run();
23515		
23516		initEvents();
23517	}
23518	
23519	
23520	
23521}
23522
23523
23524
23525/**
23526 * carousel class
23527 */
23528function UGCarousel(){
23529
23530	var t = this, g_objThis = jQuery(this);
23531	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objWrapper;	
23532	var g_functions = new UGFunctions(), g_arrItems, g_objTileDesign = new UGTileDesign();
23533	var g_thumbs = new UGThumbsGeneral(), g_objCarouselWrapper, g_objInner, arrOrigTiles = [];
23534	
23535	var g_options = {
23536			carousel_padding: 8,							//padding at the sides of the carousel
23537			carousel_space_between_tiles: 20,				//space between tiles
23538			carousel_navigation_numtiles:3,					//number of tiles to scroll when user clicks on next/prev button
23539			carousel_scroll_duration:500,					//duration of scrolling to tile
23540			carousel_scroll_easing:"easeOutCubic",			//easing of scrolling to tile animation
23541			
23542			carousel_autoplay: true,						//true,false - autoplay of the carousel on start
23543			carousel_autoplay_timeout: 3000,				//autoplay timeout
23544			carousel_autoplay_direction: "right",			//left,right - autoplay direction
23545			carousel_autoplay_pause_onhover: true,			//pause the autoplay on mouse over
23546			carousel_vertical_scroll_ondrag: false			//vertical screen scroll on carousel drag
23547	};
23548	
23549	this.events = {
23550			START_PLAY: "carousel_start_play",
23551			PAUSE_PLAY: "carousel_pause_play",
23552			STOP_PLAY: "carousel_stop_play"
23553	};
23554	
23555	var g_temp = {
23556			eventSizeChange: "thumb_size_change",
23557			isFirstTimeRun:true,  //if run once
23558			carouselMaxWidth: null,
23559			tileWidth:0,
23560			initTileWidth:0,
23561			initTileHeight:0,
23562			sideSpace:1500,				//the space that must be filled with items
23563			spaceActionSize:500,
23564			numCurrent:0,
23565			touchActive: false,
23566			startInnerPos: 0,
23567			lastTime:0,
23568			startTime:0,
23569			startMousePos:0,
23570			lastMousePos:0,
23571			scrollShortDuration: 200,
23572			scrollShortEasing: "easeOutQuad",
23573			handle:null,
23574			isPlayMode: false,
23575			isPaused: false,
23576			storedEventID: "carousel"
23577	};
23578
23579	
23580	function __________GENERAL_________(){};
23581	
23582	/**
23583	 * init the gallery
23584	 */
23585	function init(gallery, customOptions){
23586		
23587		g_objects = gallery.getObjects();
23588		g_gallery = gallery;
23589		g_objGallery = jQuery(gallery);
23590		g_objWrapper = g_objects.g_objWrapper;
23591		g_arrItems = g_objects.g_arrItems;
23592		
23593		g_options = jQuery.extend(g_options, customOptions);
23594		
23595		g_objTileDesign.setFixedMode();		
23596		g_objTileDesign.setApproveClickFunction(isApproveTileClick);
23597		g_objTileDesign.init(gallery, g_options);
23598		
23599		g_thumbs = g_objTileDesign.getObjThumbs();
23600		g_options = g_objTileDesign.getOptions();
23601		
23602		g_temp.initTileWidth = g_options.tile_width;
23603		g_temp.initTileHeight = g_options.tile_height;
23604		
23605		g_temp.tileWidth = g_options.tile_width;
23606	}
23607	
23608	
23609	/**
23610	 * set the grid panel html
23611	 */
23612	function setHtml(objParent){
23613		
23614		if(!objParent)
23615			var objParent = g_objWrapper;
23616		
23617		var html = "<div class='ug-carousel-wrapper'><div class='ug-carousel-inner'></div></div>";
23618		g_objWrapper.append(html);
23619		
23620		g_objCarouselWrapper = g_objWrapper.children(".ug-carousel-wrapper");
23621		g_objInner = g_objCarouselWrapper.children(".ug-carousel-inner");
23622		
23623		g_objTileDesign.setHtml(g_objInner);
23624		
23625		g_thumbs.getThumbs().fadeTo(0,1);
23626		
23627	}
23628	
23629	
23630	/**
23631	 * resize tiles to new width / height
23632	 */
23633	function resizeTiles(newTileWidth, newTileHeight){
23634		
23635		if(!newTileHeight){
23636			
23637			var newTileHeight = g_temp.initTileHeight / g_temp.initTileWidth * newTileWidth;
23638			
23639		}
23640		
23641		g_temp.tileWidth = newTileWidth;
23642		
23643		//update all options
23644		var optUpdate = {
23645				tile_width: newTileWidth, 
23646				tile_height: newTileHeight
23647		};
23648		
23649		g_objTileDesign.setOptions(optUpdate);
23650		
23651		g_options.tile_width = newTileWidth;
23652		g_options.tile_height = newTileHeight;
23653		
23654		//resize all tiles
23655		g_objTileDesign.resizeAllTiles(newTileWidth);
23656		
23657		//reposition tiles
23658		positionTiles(true);		//must to position tiles right after size change, for inner size change
23659	}
23660	
23661	/**
23662	 * run the gallery after init and set html
23663	 */
23664	function run(){
23665		
23666		//validation
23667		if(g_temp.carouselMaxWidth === null){
23668			throw new Error("The carousel width not set");
23669			return(false);
23670		}
23671		
23672		//if the size changed, change it anyway
23673		if(g_temp.tileWidth < g_temp.initTileWidth){
23674						
23675			var newTileWidth = g_temp.carouselMaxWidth - g_options.carousel_padding * 2;
23676			if(newTileWidth > g_temp.initTileWidth)
23677				newTileWidth = g_temp.initTileWidth;
23678			
23679			resizeTiles(newTileWidth);
23680			
23681			var numTiles = g_functions.getNumItemsInSpace(g_temp.carouselMaxWidth, newTileWidth, g_options.carousel_space_between_tiles);
23682			
23683		}else{
23684			
23685			//check if need to lower tiles size
23686			var numTiles = g_functions.getNumItemsInSpace(g_temp.carouselMaxWidth, g_temp.tileWidth, g_options.carousel_space_between_tiles);
23687			
23688			//if no tiles fit, resize the tiles
23689			if(numTiles <= 0){
23690				numTiles = 1;
23691				
23692				var newTileWidth = g_temp.carouselMaxWidth - g_options.carousel_padding * 2;
23693				
23694				resizeTiles(newTileWidth);
23695			}
23696			
23697		}
23698				
23699		//set wrapper width
23700		var realWidth = g_functions.getSpaceByNumItems(numTiles, g_temp.tileWidth, g_options.carousel_space_between_tiles);
23701		realWidth += g_options.carousel_padding * 2;
23702		
23703		g_objCarouselWrapper.width(realWidth);
23704		
23705		if(g_temp.isFirstTimeRun == true){
23706			
23707			initEvents();
23708			
23709			g_objTileDesign.run();
23710			
23711			//set data indexes to tiles
23712			jQuery.each(g_arrItems, function(index, item){
23713				item.objThumbWrapper.data("index", index);
23714
23715				g_objWrapper.trigger(g_temp.eventSizeChange, [item.objThumbWrapper,true]);
23716				item.objTileOriginal = item.objThumbWrapper.clone(true, true);
23717			});
23718						
23719			positionTiles(true);		//set heights at first time
23720			
23721			if(g_options.carousel_autoplay == true)
23722				t.startAutoplay();
23723		}else{
23724			
23725			if(g_options.carousel_autoplay == true)
23726				t.pauseAutoplay();
23727			
23728			scrollToTile(0, false);
23729			
23730			if(g_options.carousel_autoplay == true)
23731				t.startAutoplay();
23732		}
23733		
23734		positionElements();
23735		
23736		g_temp.isFirstTimeRun = false;
23737	}
23738	
23739	
23740	
23741	function __________GETTERS_______(){};
23742	
23743	/**
23744	 * get inner position
23745	 */
23746	function getInnerPos(){
23747		return g_functions.getElementSize(g_objInner).left;
23748	}
23749	
23750	/**
23751	 * get mouse position
23752	 */
23753	function getMousePos(event){
23754		return g_functions.getMousePosition(event).pageX;
23755	}
23756	
23757	
23758	/**
23759	 * get all tiles
23760	 */
23761	function getTiles(){
23762		
23763		var objTiles = g_objInner.children(".ug-thumb-wrapper");
23764		
23765		return(objTiles);
23766	}
23767	
23768	
23769	/**
23770	 * get num tiles in some space
23771	 */
23772	function getNumTilesInSpace(space){
23773		
23774		var numItems = g_functions.getNumItemsInSpace(space, g_temp.tileWidth, g_options.carousel_space_between_tiles)
23775				
23776		return(numItems);
23777	}
23778	
23779	
23780	/**
23781	 * get num tiles
23782	 */
23783	function getNumTiles(){
23784		return getTiles().length;
23785	}
23786	
23787	
23788	/**
23789	 * get tile
23790	 */
23791	function getTile(numTile){
23792		validateTileNum(numTile);
23793		var objTiles = getTiles();
23794		var objTile = jQuery(objTiles[numTile]);
23795		
23796		return(objTile);
23797	}
23798	
23799	
23800	/**
23801	 * get first tile in the inner object
23802	 */
23803	function getFirstTile(){
23804				
23805		return g_objInner.children(".ug-thumb-wrapper").first();
23806	}
23807	
23808	/**
23809	 * get last tile in the inner object
23810	 */
23811	function getLastTile(){
23812		
23813		return g_objInner.children(".ug-thumb-wrapper").last();		
23814	}
23815	
23816	
23817	
23818	/**
23819	 * get clone of the time next or prev the given
23820	 */
23821	function getTileClones(objTile, numClones, dir){
23822		
23823		var index = objTile.data("index");
23824		if(index == undefined){
23825			throw new Error("every tile should have index!");			
23826		}
23827		
23828		var arrClonedItems = [];
23829		
23830		for(var i=0;i<numClones;i++){			
23831			
23832			if(dir == "prev")
23833				var itemToAdd = g_gallery.getPrevItem(index, true);
23834			else
23835				var itemToAdd = g_gallery.getNextItem(index, true);
23836			
23837			if(!itemToAdd){
23838				throw new Error("the item to add is empty");
23839			}
23840			
23841			var clonedTile = itemToAdd.objTileOriginal.clone(true, true);
23842			
23843			
23844			index = itemToAdd.index;	
23845			
23846			clonedTile.addClass("cloned");
23847			arrClonedItems.push(clonedTile);
23848		}
23849		
23850		return(arrClonedItems);
23851	}
23852	
23853	
23854	/**
23855	 * get space left from the right
23856	 */
23857	function getRemainSpaceRight(){
23858		var wrapperSize = g_functions.getElementSize(g_objCarouselWrapper);
23859		var innerSize = g_functions.getElementSize(g_objInner);
23860		
23861		var spaceTaken = innerSize.width - wrapperSize.width + innerSize.left;
23862		var spaceRemain = g_temp.sideSpace - spaceTaken;
23863				
23864		return(spaceRemain);
23865	}
23866	
23867	
23868	/**
23869	 * get remain space on the left
23870	 */
23871	function getRemainSpaceLeft(){
23872		var spaceTaken = -getInnerPos();
23873		var spaceRemain = g_temp.sideSpace - spaceTaken;
23874		return(spaceRemain);
23875	}
23876	
23877	/**
23878	 * get carousel width
23879	 */
23880	function getCarouselWidth(){
23881		
23882		var objSize = g_functions.getElementSize(g_objCarouselWrapper);
23883		return(objSize.width);
23884	}
23885	
23886	/**
23887	 * get num tiles in the carousel
23888	 */
23889	function getNumTilesInCarousel(){
23890		
23891		var width = getCarouselWidth();
23892		
23893		var numTiles = getNumTilesInSpace(width);
23894		
23895		return(numTiles);
23896	}
23897	
23898	
23899	function __________OTHER_METHODS_______(){};
23900	
23901	
23902	/**
23903	 * position existing tiles
23904	 */
23905	function positionTiles(setHeight){
23906		
23907		if(!setHeight)
23908			var setHeight = false;
23909		
23910		var objTiles = getTiles();
23911				
23912		var posx = 0;
23913		var maxHeight = 0, totalWidth;
23914		
23915		jQuery.each(objTiles, function(index, objTile){
23916			objTile = jQuery(objTile);
23917			g_functions.placeElement(objTile, posx, 0);
23918			var tileSize = g_functions.getElementSize(objTile);
23919			posx += tileSize.width + g_options.carousel_space_between_tiles;
23920			maxHeight = Math.max(maxHeight, tileSize.height);
23921			if(index == (objTiles.length-1))
23922				totalWidth = tileSize.right;
23923		});
23924		
23925		//set heights and widths
23926		g_objInner.width(totalWidth);
23927				
23928		maxHeight += g_options.carousel_padding * 2;
23929		
23930		if(setHeight === true){
23931			g_objInner.height(maxHeight);
23932			g_objCarouselWrapper.height(maxHeight);
23933		}
23934				
23935		scrollToTile(g_temp.numCurrent, false);
23936
23937		return(totalWidth);
23938	}
23939	
23940	
23941	/**
23942	 * validate that the num not more then num tiles
23943	 */
23944	function validateTileNum(numTile){
23945
23946		if(numTile > (getTiles().length-1))
23947			throw new Error("Wrogn tile number: " + numTile);
23948	}
23949	
23950	
23951	/**
23952	 * add tile to left
23953	 */
23954	function addTiles(numTiles, dir){
23955		
23956		if(dir == "left")
23957			var anchorTile = getFirstTile();
23958		else
23959			var anchorTile = getLastTile();
23960		
23961		var clonesType = (dir == "left")?"prev":"next";
23962		
23963		var arrNewTiles = getTileClones(anchorTile, numTiles, clonesType);
23964				
23965		jQuery.each(arrNewTiles, function(index, objTile){		
23966			
23967			if(dir == "left")
23968				g_objInner.prepend(objTile);
23969			else
23970				g_objInner.append(objTile);
23971			
23972			g_objWrapper.trigger(g_temp.eventSizeChange, objTile);
23973			g_objTileDesign.loadTileImage(objTile);
23974			
23975		});
23976		
23977		
23978	}
23979	
23980	/**
23981	 * remove some tiles
23982	 */
23983	function removeTiles(numTilesToRemove, direction){
23984		
23985		validateTileNum(numTiles);
23986		
23987		var arrTiles = getTiles();
23988		var numTiles = arrTiles.length;
23989		
23990		for(var i=0; i<numTilesToRemove; i++){
23991			
23992			if(direction == "left")
23993				jQuery(arrTiles[i]).remove();
23994			else{
23995				jQuery(arrTiles[numTiles-1-i]).remove();
23996			}
23997		}
23998	}
23999
24000	
24001	/**
24002	 * set inner strip position
24003	 */
24004	function setInnerPos(pos){
24005		var objCss = {
24006				"left":pos+"px"
24007		};
24008		
24009		g_objInner.css(objCss);
24010	}
24011	
24012	
24013	/**
24014	 * scroll to tile by number
24015	 */
24016	function scrollToTile(numTile, isAnimation, isShort){
24017		
24018		if(isAnimation === undefined){
24019			var isAnimation = true;
24020			if(g_objInner.is(":animated"))
24021				return(true);
24022		}
24023				
24024		var objTile = getTile(numTile);
24025		var objSize = g_functions.getElementSize(objTile);
24026		var posScroll = -objSize.left + g_options.carousel_padding;
24027		
24028		var objCss = {
24029				"left":posScroll+"px"
24030		};
24031						
24032		if(isAnimation === true){
24033			
24034			var duration = g_options.carousel_scroll_duration;
24035			var easing = g_options.carousel_scroll_easing;
24036			
24037			if(isShort === true){
24038				duration = g_temp.scrollShortDuration;
24039				easing = g_temp.scrollShortEasing;
24040			}
24041			
24042			g_objInner.stop(true).animate(objCss ,{
24043				duration: duration,
24044				easing: easing,
24045				queue: false,
24046				//progress:function(){t.triggerStripMoveEvent()},
24047				complete: function(){
24048					g_temp.numCurrent = numTile;
24049					
24050					fillSidesWithTiles(true);
24051				}
24052			});					
24053			
24054		}else{
24055			g_temp.numCurrent = numTile;
24056						
24057			g_objInner.css(objCss);
24058		}
24059		
24060	}
24061	
24062	
24063	/**
24064	 * get number of neerest tile
24065	 */
24066	function getNeerestTileNum(){
24067		var innerPos = -getInnerPos();
24068		var numTiles = getNumTilesInSpace(innerPos);
24069		var tile1Pos = g_functions.getElementSize(getTile(numTiles)).left;
24070		var tile2Pos = g_functions.getElementSize(getTile(numTiles+1)).left;
24071				
24072		if(Math.abs(tile1Pos - innerPos) < Math.abs(tile2Pos - innerPos))
24073			return(numTiles);
24074		else			
24075			return(numTiles+1);
24076	}
24077	
24078	
24079	/**
24080	 * get neerest tile to inner position
24081	 */
24082	function scrollToNeerestTile(){
24083		
24084		var tileNum = getNeerestTileNum();
24085		scrollToTile(tileNum, true, true);
24086	}
24087	
24088	
24089	/**
24090	 * fill the sides with tiles till it fil the sideSpace
24091	 */
24092	function fillSidesWithTiles(){
24093				
24094		var spaceLeft = getRemainSpaceLeft();
24095		var spaceRight = getRemainSpaceRight();
24096		
24097		var numItemsLeft = 0, numItemsRight = 0, numItemsRemoveLeft = 0, numItemsRemoveRight = 0;
24098		
24099		//trace("left: " + spaceLeft+ " right: " + spaceRight);
24100		
24101		var numTiles = getNumTiles();
24102		
24103		//add tiles to left
24104		if(spaceLeft > g_temp.spaceActionSize){
24105			numItemsLeft = getNumTilesInSpace(spaceLeft);		
24106			addTiles(numItemsLeft, "left");
24107			
24108			g_temp.numCurrent += numItemsLeft;
24109			
24110		}else if(spaceLeft < -g_temp.spaceActionSize){
24111			var numItemsRemoveLeft = getNumTilesInSpace(Math.abs(spaceLeft));
24112			removeTiles(numItemsRemoveLeft, "left");
24113			g_temp.numCurrent -= numItemsRemoveLeft;
24114		}
24115		
24116		//add tiles to right
24117		if(spaceRight > g_temp.spaceActionSize){
24118			numItemsRight = getNumTilesInSpace(spaceRight);
24119			addTiles(numItemsRight, "right");			
24120		}else if(spaceRight < -g_temp.spaceActionSize){
24121			numItemsRemoveRight = getNumTilesInSpace(Math.abs(spaceRight));
24122			removeTiles(numItemsRemoveRight, "right");			
24123		}
24124		
24125		
24126		//small validation
24127		if(numItemsRemoveRight > numTiles){
24128			
24129			throw new Error("Can't remove more then num tiles");
24130		}
24131			
24132		//trace(numItemsRemoveRight);
24133		//trace("numItems: " + getNumTiles());
24134		
24135		//scroll to tile and position inner object
24136		var isPositioned = false;
24137		if(numItemsLeft || numItemsRight || numItemsRemoveLeft || numItemsRemoveRight){
24138			
24139			/*
24140			debugLine({
24141				numItemsLeft:numItemsLeft,
24142				numItemsRight:numItemsRight,
24143				numItemsRemoveLeft:numItemsRemoveLeft,
24144				numItemsRemoveRight: numItemsRemoveRight
24145			});
24146			*/
24147			//trace("do something");
24148			
24149			positionTiles();			
24150			isPositioned = true
24151		}
24152		
24153		return(isPositioned);
24154	}
24155	
24156	
24157	/**
24158	 * position tiles
24159	 */
24160	function positionElements(isFirstTime){
24161				
24162		//position inner strip
24163		g_functions.placeElement(g_objInner, 0, g_options.carousel_padding);
24164		
24165		//position sides
24166		fillSidesWithTiles();
24167		
24168	}
24169	
24170	
24171	
24172	function __________AUTOPLAY_______(){};
24173
24174	/**
24175	 * start autoplay
24176	 */
24177	this.startAutoplay = function(){
24178		
24179		g_temp.isPlayMode = true;
24180		g_temp.isPaused = false;
24181		
24182		g_objThis.trigger(t.events.START_PLAY);
24183		
24184		if(g_temp.handle)
24185			clearInterval(g_temp.handle);
24186		
24187		g_temp.handle = setInterval(autoplayStep, g_options.carousel_autoplay_timeout);
24188		
24189	}
24190	
24191	
24192	/**
24193	 * unpause autoplay after pause
24194	 */
24195	this.unpauseAutoplay = function(){
24196		
24197		if(g_temp.isPlayMode == false)
24198			return(true);
24199		
24200		if(g_temp.isPaused == false)
24201			return(true);
24202		
24203		t.startAutoplay();
24204	}
24205	
24206	
24207	/**
24208	 * pause the autoplay
24209	 */
24210	this.pauseAutoplay = function(){
24211
24212		if(g_temp.isPlayMode == false)
24213			return(true);
24214		
24215		g_temp.isPaused = true;
24216		
24217		if(g_temp.handle)
24218			clearInterval(g_temp.handle);
24219		
24220		g_objThis.trigger(t.events.PAUSE_PLAY);
24221		
24222	}
24223
24224	
24225	/**
24226	 * stop autoplay
24227	 */
24228	this.stopAutoplay = function(){
24229		
24230		if(g_temp.isPlayMode == false)
24231			return(true);
24232		
24233		g_temp.isPaused = false;
24234		g_temp.isPlayMode = false;
24235		
24236		if(g_temp.handle)
24237			clearInterval(g_temp.handle);
24238		
24239		g_objThis.trigger(t.events.STOP_PLAY);
24240	}
24241	
24242	
24243	/**
24244	 * autoplay step, advance the carousel by 1
24245	 */
24246	function autoplayStep(){
24247		
24248		if(g_options.carousel_autoplay_direction == "left"){
24249			t.scrollRight(1);
24250		}else{
24251			t.scrollLeft(1);
24252		}
24253		
24254	}
24255	
24256	function __________EVENTS_______(){};
24257		
24258	
24259	/**
24260	 * on touch start
24261	 */
24262	function onTouchStart(event){
24263		
24264		if(g_temp.touchActive == true)
24265			return(true);
24266		
24267		g_temp.touchActive = true;
24268		
24269		t.pauseAutoplay();
24270		
24271		g_temp.startTime = jQuery.now();	
24272		g_temp.startMousePos = getMousePos(event);
24273		g_temp.startInnerPos = getInnerPos();
24274		g_temp.lastTime = g_temp.startTime;
24275		g_temp.lastMousePos = g_temp.startMousePos;
24276		
24277		g_functions.storeEventData(event, g_temp.storedEventID);
24278	}
24279
24280	
24281	/**
24282	 * on touch move
24283	 */
24284	function onTouchMove(event){
24285				
24286		if(g_temp.touchActive == false)
24287			return(true);
24288		
24289		g_functions.updateStoredEventData(event, g_temp.storedEventID);
24290		
24291		event.preventDefault();
24292		
24293		var scrollDir = null;
24294		
24295		if(g_options.carousel_vertical_scroll_ondrag == true)
24296			scrollDir = g_functions.handleScrollTop(g_temp.storedEventID);
24297		
24298		if(scrollDir === "vert")
24299			return(true);
24300		
24301		g_temp.lastMousePos = getMousePos(event);
24302		
24303		var diff = g_temp.lastMousePos - g_temp.startMousePos;
24304		var innerPos = g_temp.startInnerPos + diff;
24305		var direction = (diff > 0) ? "prev":"next";
24306		var innerSize = g_functions.getElementSize(g_objInner).width;
24307		
24308		//slow down when off limits
24309		if(innerPos > 0 && direction == "prev"){
24310			innerPos = innerPos / 3;
24311		}
24312		
24313		if(innerPos < -innerSize && direction == "next"){
24314			innerPos = g_temp.startInnerPos + diff / 3;
24315		}
24316		
24317		setInnerPos(innerPos);
24318	}
24319	
24320	
24321	/**
24322	 * on touch end
24323	 * change panes or return to current pane
24324	 */
24325	function onTouchEnd(event){
24326		
24327		if(g_temp.touchActive == false)
24328			return(true);
24329		
24330		//event.preventDefault();
24331		g_temp.touchActive = false;
24332		
24333		scrollToNeerestTile();
24334		
24335		t.unpauseAutoplay();
24336	}
24337	
24338	/**
24339	 * pause the playing
24340	 */
24341	function onMouseEnter(event){
24342		
24343		if(g_options.carousel_autoplay_pause_onhover == false)
24344			return(true);
24345		
24346		if(g_temp.isPlayMode == true && g_temp.isPaused == false)
24347			t.pauseAutoplay();
24348	}
24349	
24350	/**
24351	 * start the playing again
24352	 */
24353	function onMouseLeave(event){
24354		
24355		if(g_options.carousel_autoplay_pause_onhover == false)
24356			return(true);
24357		
24358		t.unpauseAutoplay();
24359	}
24360	
24361	
24362	/**
24363	 * init panel events
24364	 */
24365	function initEvents(){
24366				
24367		g_objTileDesign.initEvents();
24368		
24369		//touch drag events
24370		//slider mouse down - drag start
24371		g_objCarouselWrapper.bind("mousedown touchstart",onTouchStart);
24372		
24373		//on body move
24374		jQuery("body").bind("mousemove touchmove",onTouchMove);
24375		
24376		//on body mouse up - drag end
24377		jQuery(window).add("body").bind("mouseup touchend", onTouchEnd);
24378		
24379		g_objCarouselWrapper.hover(onMouseEnter, onMouseLeave);
24380		
24381	}
24382	
24383	
24384	/**
24385	 * destroy the carousel events
24386	 */
24387	this.destroy = function(){
24388		
24389		if(g_temp.handle)
24390			clearInterval(g_temp.handle);
24391		
24392		g_objThis.off(t.events.START_PLAY);		
24393		g_objThis.off(t.events.STOP_PLAY);		
24394		
24395		//touch drag events
24396		//slider mouse down - drag start
24397		g_objCarouselWrapper.unbind("mousedown");
24398		g_objCarouselWrapper.unbind("touchstart");
24399		
24400		//on body move
24401		jQuery("body").unbind("mousemove");
24402		jQuery("body").unbind("touchmove");
24403		
24404		//on body mouse up - drag end
24405		jQuery(window).add("body").unbind("mouseup").unbind("touchend");
24406		
24407		g_objCarouselWrapper.off("mouseenter").off("mouseleave");
24408		
24409		g_objTileDesign.destroy();
24410	}
24411
24412	
24413	/**
24414	 * init function for avia controls
24415	 */
24416	this.init = function(gallery, customOptions, width){
24417		if(width)
24418			this.setMaxWidth(width);
24419		
24420		init(gallery, customOptions);
24421	}
24422
24423	
24424	/**
24425	 * set the width
24426	 */
24427	this.setMaxWidth = function(width){
24428		
24429		g_temp.carouselMaxWidth = width;
24430	}
24431	
24432	
24433	/**
24434	 * set html
24435	 */
24436	this.setHtml = function(objParent){
24437		setHtml(objParent);
24438	}
24439	
24440	/**
24441	 * get the carousel element
24442	 */
24443	this.getElement = function(){
24444		return g_objCarouselWrapper;
24445	}
24446	
24447	/**
24448	 * get tile design object
24449	 */
24450	this.getObjTileDesign = function(){
24451		return(g_objTileDesign);
24452	}
24453	
24454	
24455	/**
24456	 * get estimated height
24457	 */
24458	this.getEstimatedHeight = function(){
24459		var height = g_options.tile_height + g_options.carousel_padding * 2;
24460		return(height);
24461	}
24462	
24463	
24464	/**
24465	 * set html and properties
24466	 */	
24467	this.run = function(){
24468		run();
24469	}
24470	
24471	
24472	/**
24473	 * scroll to right
24474	 */
24475	this.scrollRight = function(tilesToScroll){
24476		
24477		if(!tilesToScroll || typeof tilesToScroll == "object")
24478			var tilesToScroll = g_options.carousel_navigation_numtiles;
24479
24480		var numTilesInCarousel = getNumTilesInCarousel();
24481		if(tilesToScroll > numTilesInCarousel)
24482			tilesToScroll = numTilesInCarousel;
24483		
24484		var numPrev = g_temp.numCurrent - tilesToScroll;
24485		if(numPrev <=0)
24486			numPrev = 0;
24487		
24488		scrollToTile(numPrev);
24489	}
24490	
24491	
24492	/**
24493	 * scroll to left
24494	 */
24495	this.scrollLeft = function(tilesToScroll){
24496				
24497		if(!tilesToScroll || typeof tilesToScroll == "object")
24498			var tilesToScroll = g_options.carousel_navigation_numtiles;
24499		
24500		var numTilesInCarousel = getNumTilesInCarousel();
24501		if(tilesToScroll > numTilesInCarousel)
24502			tilesToScroll = numTilesInCarousel;
24503		
24504		var numTiles = getNumTiles();
24505		
24506		var numNext = g_temp.numCurrent + tilesToScroll;
24507		if(numNext >= numTiles)
24508			numNext = numTiles-1;
24509	
24510		scrollToTile(numNext);
24511	}
24512	
24513	/**
24514	 * set scroll left button
24515	 */
24516	this.setScrollLeftButton = function(objButton){
24517		g_functions.setButtonMobileReady(objButton);
24518		g_functions.setButtonOnClick(objButton, t.scrollLeft);
24519	}
24520	
24521	
24522	/**
24523	 * set scroll right button
24524	 */
24525	this.setScrollRightButton = function(objButton){
24526		g_functions.setButtonMobileReady(objButton);
24527		g_functions.setButtonOnClick(objButton, t.scrollRight);
24528	}
24529	
24530	
24531	/**
24532	 * set scroll right button
24533	 */
24534	this.setPlayPauseButton = function(objButton){
24535		g_functions.setButtonMobileReady(objButton);
24536		
24537		if(g_temp.isPlayMode == true && g_temp.isPaused == false){
24538			objButton.addClass("ug-pause-icon");			
24539		}
24540		
24541		g_objThis.on(t.events.START_PLAY, function(){
24542			objButton.addClass("ug-pause-icon");
24543		});
24544		
24545		g_objThis.on(t.events.STOP_PLAY, function(){
24546			objButton.removeClass("ug-pause-icon");
24547		});
24548		
24549		g_functions.setButtonOnClick(objButton, function(){
24550				
24551				if(g_temp.isPlayMode == false || g_temp.isPaused == true)					
24552					t.startAutoplay();
24553				else
24554					t.stopAutoplay();
24555				
24556		});
24557	}
24558	
24559	
24560	/**
24561	 * return if passed some significant movement
24562	 */
24563	function isApproveTileClick(){
24564		
24565		var passedTime = g_temp.lastTime - g_temp.startTime;		
24566		var passedDistanceAbs = Math.abs(g_temp.lastMousePos - g_temp.startMousePos);
24567		
24568		if(passedTime > 300)
24569			return(false);
24570		
24571		if(passedDistanceAbs > 30)
24572			return(false);
24573		
24574		return(true);
24575	}
24576	
24577	
24578}
24579
24580
24581
24582/**
24583 tabs panel class addon to unite gallery
24584 */
24585function UGTabs(){
24586	
24587	var t = this, g_objThis = jQuery(this),g_objGallery;
24588	var g_gallery = new UniteGalleryMain(), g_functions = new UGFunctions();
24589	var g_objTabs, g_objSelect;
24590	
24591
24592	var g_options = {
24593		tabs_type:"tabs",					//tabs type: tabs, select
24594		tabs_container: "#ug_tabs",			//tabs container
24595		tabs_class_selected: "ug-tab-selected"
24596	};
24597	
24598	this.events = {
24599		
24600	};
24601	
24602	
24603	/**
24604	 * init tabs function
24605	 */
24606	function initTabs(gallery, customOptions){
24607		g_gallery = gallery;
24608		
24609		g_objGallery = jQuery(g_gallery);
24610		
24611		g_options = jQuery.extend(g_options, customOptions);
24612		
24613		if(g_options.tabs_type == "select")
24614			g_objSelect = jQuery(g_options.tabs_container);
24615		else
24616			g_objTabs = jQuery(g_options.tabs_container + " .ug-tab");
24617		
24618	}
24619	
24620	
24621	
24622	/**
24623	 * run the tabs
24624	 */
24625	function runTabs(){
24626				
24627		initEvents();
24628	}
24629	
24630	
24631	/**
24632	 * request new gallery items
24633	 */
24634	function requestGalleryItems(catid){
24635		
24636		g_gallery.requestNewItems(catid);
24637		
24638	}
24639	
24640	
24641	/**
24642	 * on tab click
24643	 */
24644	function onTabClick(){
24645		
24646		var classSelected = g_options.tabs_class_selected;
24647		
24648		var objTab = jQuery(this);
24649		if(objTab.hasClass(classSelected))
24650			return(true);
24651		
24652		g_objTabs.not(objTab).removeClass(classSelected);
24653		objTab.addClass(classSelected);
24654		
24655		var catID = objTab.data("catid");
24656		if(!catID)
24657			return(true);
24658		
24659		requestGalleryItems(catID);
24660		
24661	}
24662	
24663	
24664	/**
24665	 * on select change
24666	 */
24667	function onSelectChange(){
24668		var objSelect = jQuery(this);
24669		var catID = objSelect.val();
24670		
24671		if(!catID)
24672			return(true);
24673		
24674		requestGalleryItems(catID);
24675	}
24676	
24677	
24678	/**
24679	 * init tabs events
24680	 */
24681	function initEvents(){
24682		
24683		if(g_options.tabs_type == "select")
24684			g_objSelect.change(onSelectChange);
24685		else
24686			g_objTabs.click(onTabClick);
24687	}
24688	
24689	/**
24690	 * destroy
24691	 */
24692	this.destroy = function(){
24693		
24694		if(g_objSelect)
24695			g_objSelect.off("change");
24696		
24697		if(g_objTabs)
24698			g_objTabs.off("click");
24699	}
24700	
24701	
24702	/**
24703	 * outer init function, move to inner init
24704	 */
24705	this.init = function(gallery, customOptions){
24706		initTabs(gallery, customOptions);
24707	}
24708	
24709	
24710	/**
24711	 * run the tabs
24712	 */
24713	this.run = function(){
24714		
24715		runTabs();
24716	}
24717	
24718	
24719}
24720
24721
24722/**
24723 * API Class
24724 * addon to Unite gallery
24725 */
24726function UG_API(gallery){
24727	
24728	var t = this, g_objThis = jQuery(t);
24729	var g_gallery = new UniteGalleryMain(), g_objGallery;
24730	var g_arrEvents = [];
24731	
24732	g_gallery = gallery;
24733	g_objGallery = jQuery(gallery);
24734	
24735	
24736	this.events = {
24737			API_INIT_FUNCTIONS:"api_init",
24738			API_ON_EVENT:"api_on_event"
24739	}
24740	
24741	
24742	/**
24743	 * get item data for output
24744	 */
24745	function convertItemDataForOutput(item){
24746		
24747		var output = {
24748				index: item.index,
24749				title: item.title,
24750				description: item.description,
24751				urlImage: item.urlImage,
24752				urlThumb: item.urlThumb
24753			};
24754			
24755			//add aditional variables to the output
24756			var addData = item.objThumbImage.data();
24757			
24758			for(var key in addData){
24759				switch(key){
24760					case "image":
24761					case "description":
24762						continue;
24763					break;
24764				}
24765				output[key] = addData[key];
24766			}
24767			
24768			return(output);
24769	}
24770	
24771	
24772	/**
24773	 * event handling function
24774	 */
24775	this.on = function(event, handlerFunction, notCache){
24776		
24777		//remember cache
24778		if(notCache !== true){
24779			g_arrEvents.push({event:event,func:handlerFunction});
24780		}
24781		
24782		switch(event){
24783			case "item_change":
24784				
24785				g_objGallery.on(g_gallery.events.ITEM_CHANGE, function(){
24786						var currentItem = g_gallery.getSelectedItem();
24787						var output = convertItemDataForOutput(currentItem);
24788						handlerFunction(output.index, output);
24789				});
24790				
24791			break;
24792			case "resize":
24793				g_objGallery.on(g_gallery.events.SIZE_CHANGE, handlerFunction);
24794			break;
24795			case "enter_fullscreen":
24796				g_objGallery.on(g_gallery.events.ENTER_FULLSCREEN, handlerFunction);				
24797			break;
24798			case "exit_fullscreen":
24799				g_objGallery.on(g_gallery.events.EXIT_FULLSCREEN, handlerFunction);				
24800			break;
24801			case "play":
24802				g_objGallery.on(g_gallery.events.START_PLAY, handlerFunction);				
24803			break;
24804			case "stop":
24805				g_objGallery.on(g_gallery.events.STOP_PLAY, handlerFunction);				
24806			break;
24807			case "pause":
24808				g_objGallery.on(g_gallery.events.PAUSE_PLAYING, handlerFunction);				
24809			break;
24810			case "continue":
24811				g_objGallery.on(g_gallery.events.CONTINUE_PLAYING, handlerFunction);
24812			break;
24813			case "open_lightbox":
24814				g_objGallery.on(g_gallery.events.OPEN_LIGHTBOX, handlerFunction);
24815			break;
24816			case "close_lightbox":
24817				g_objGallery.on(g_gallery.events.CLOSE_LIGHTBOX, handlerFunction);
24818			break;
24819			default:
24820				if(console)
24821					console.log("wrong api event: " + event);
24822			break;
24823		}
24824		
24825		g_objGallery.trigger(t.events.API_ON_EVENT, [event, handlerFunction]);
24826	}
24827	
24828	
24829	/**
24830	 * start playing 
24831	 */
24832	this.play = function(){		
24833		g_gallery.startPlayMode();		
24834	}
24835	
24836	
24837	/**
24838	 * stop playing
24839	 */
24840	this.stop = function(){
24841		g_gallery.stopPlayMode();
24842	}
24843	
24844	
24845	/**
24846	 * toggle playing
24847	 */
24848	this.togglePlay = function(){
24849		g_gallery.togglePlayMode();
24850	}
24851	
24852	
24853	/**
24854	 * enter fullscreen
24855	 */
24856	this.enterFullscreen = function(){
24857		g_gallery.toFullScreen();
24858	}
24859	
24860	/**
24861	 * exit fullscreen
24862	 */
24863	this.exitFullscreen = function(){
24864		g_gallery.exitFullScreen();
24865	}
24866	
24867	/**
24868	 * toggle fullscreen
24869	 */
24870	this.toggleFullscreen = function(){
24871		
24872		g_gallery.toggleFullscreen();		
24873	}
24874	
24875	
24876	/**
24877	 * reset zoom
24878	 */
24879	this.resetZoom = function(){
24880		var objSlider = g_gallery.getObjSlider();
24881		if(!objSlider)
24882			return(false);
24883		
24884		objSlider.zoomBack();
24885	}
24886	
24887	
24888	/**
24889	 * zoom in
24890	 */
24891	this.zoomIn = function(){
24892		
24893		var objSlider = g_gallery.getObjSlider();
24894		if(!objSlider)
24895			return(false);
24896		
24897		objSlider.zoomIn();		
24898	}
24899
24900	/**
24901	 * zoom in
24902	 */
24903	this.zoomOut = function(){
24904		
24905		var objSlider = g_gallery.getObjSlider();
24906		if(!objSlider)
24907			return(false);
24908		
24909		objSlider.zoomOut();		
24910	}
24911	
24912	/**
24913	 * next item
24914	 */
24915	this.nextItem = function(){
24916		g_gallery.nextItem();
24917	}
24918	
24919	
24920	/**
24921	 * prev item
24922	 */
24923	this.prevItem = function(){
24924		g_gallery.prevItem();
24925	}
24926	
24927	/**
24928	 * go to some item by index (0-numItems)
24929	 */
24930	this.selectItem = function(numItem){
24931		
24932		g_gallery.selectItem(numItem);
24933	
24934	}
24935	
24936	
24937	/**
24938	 * resize the gallery to some width (height).
24939	 */
24940	this.resize = function(width, height){
24941		
24942		if(height)
24943			g_gallery.resize(width, height);
24944		else
24945			g_gallery.resize(width);
24946	}
24947	
24948	
24949	/**
24950	 * get some item by index
24951	 */
24952	this.getItem = function(numItem){
24953		
24954		var data = g_gallery.getItem(numItem);
24955		var output = convertItemDataForOutput(data);
24956		
24957		return(output);
24958	}
24959	
24960	
24961	/**
24962	 * get number of items in the gallery
24963	 */
24964	this.getNumItems = function(){
24965		var numItems = g_gallery.getNumItems();
24966		return(numItems);
24967	}
24968	
24969	/**
24970	 * refresh gallery with another options
24971	 */
24972	this.reloadGallery = function(customOptions){
24973		if(!customOptions)
24974			var customOptions = {};
24975		
24976		g_gallery.run(null, customOptions);
24977		
24978		//restore events:
24979		g_arrEvents.map(function(obj){
24980			t.on(obj.event,obj.func,true);
24981		});
24982		
24983	}
24984	
24985	
24986	/**
24987	 * destroy the gallery
24988	 */
24989	this.destroy = function(){
24990		g_gallery.destroy();
24991	}
24992	
24993	//trigger api on init event
24994	g_objGallery.trigger(t.events.API_INIT_FUNCTIONS, t);
24995	
24996}
24997
24998/**
24999 loadmore panel class addon to unite gallery
25000 */
25001function UGLoadMore(){
25002	
25003	var t = this, g_objThis = jQuery(this),g_objGallery;
25004	var g_gallery = new UniteGalleryMain(), g_functions = new UGFunctions();
25005	var g_objWrapper, g_objButton, g_objLoader, g_objError;
25006	
25007	var g_temp = {
25008			isInited:false
25009	}
25010	
25011	var g_options = {
25012		loadmore_container: "ug_loadmore_wrapper"			//tabs container
25013	};
25014	
25015	
25016	this.events = {
25017		
25018	};
25019	
25020	
25021	/**
25022	 * init wrapper
25023	 */
25024	function initObjects(){
25025		
25026		g_objWrapper = jQuery("#"+g_options.loadmore_container);
25027		if(g_objWrapper.length == 0)
25028			return(false);
25029		
25030		g_objButton = g_objWrapper.find(".ug-loadmore-button");
25031		if(g_objButton.length == 0)
25032			return(false);
25033		
25034		g_objLoader = g_objWrapper.find(".ug-loadmore-loader");
25035		if(g_objLoader.length == 0)
25036			return(false);
25037		
25038		g_objError = g_objWrapper.find(".ug-loadmore-error");
25039		if(g_objError.length == 0)
25040			return(false);
25041		
25042		g_temp.isInited = true;
25043	}
25044	
25045	
25046	/**
25047	 * show loadmore
25048	 */
25049	function showLoadmore(){
25050		
25051		g_objWrapper.show();
25052	}
25053	
25054	
25055	/**
25056	 * on loadore click event
25057	 */
25058	function onLoadmoreClick(){
25059		
25060		g_objButton.hide();
25061		g_objLoader.show();
25062		
25063		var data = {
25064				numitems:g_gallery.getNumItems()
25065		};
25066		
25067		g_gallery.ajaxRequest("front_loadmore", data, function(response){
25068			
25069			g_objLoader.hide();
25070			
25071			var htmlItems = response.html_items;
25072			var showLoadmore = response.show_loadmore;
25073			
25074			if(showLoadmore == true){
25075				g_objButton.blur().show();
25076				g_objLoader.hide();
25077			}else{
25078				g_objWrapper.hide();
25079			}
25080			
25081			g_gallery.addItems(htmlItems);
25082						
25083		},function(errorText){
25084			errorText = "Ajax Error!" + errorText;
25085			
25086			g_objLoader.hide();
25087			g_objError.show();
25088			g_objError.html(errorText);
25089			
25090		});
25091		
25092	}
25093	
25094	
25095	/**
25096	 * init events
25097	 */
25098	function initEvents(){
25099		
25100		g_gallery.onEvent("tiles_first_placed", showLoadmore);
25101		
25102		g_objButton.click(onLoadmoreClick);
25103	}
25104	
25105	
25106	/**
25107	 * destroy
25108	 */
25109	this.destroy = function(){
25110		if(g_temp.isInited == false)
25111			return(false);
25112	}
25113	
25114	
25115	/**
25116	 * init the loadmore button
25117	 */
25118	this.init = function(gallery, customOptions){
25119		g_gallery = gallery;
25120		
25121		g_objGallery = jQuery(g_gallery);
25122		g_options = jQuery.extend(g_options, customOptions);
25123		
25124		initObjects();
25125		
25126		if(g_temp.isInited == false){
25127			trace("load more not inited, something is wrong");
25128			return(false);
25129		}
25130		
25131		initEvents();
25132	}
25133	
25134	
25135}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.