PageSourceSearch

https://chaux-de-fonds.ch/media/system/plugins/rawunitegallery/dist/js/unitegallery.js

js chaux-de-fonds.ch collected 2026-10-02 04:54:25 UTC 579,480 bytes, 24,668 lines download raw bytes

1// Unite Gallery, Version: 1.7.40, released 29 Nov 2016 
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		handle: null			//interval handle
90	};
91	
92	this.debugVar = "";
93
94	this.z__________FULL_SCREEN___________ = function(){}
95	
96	
97	
98	/**
99	 * move to full screen mode
100	 * fullscreen ID - the ID of current fullscreen
101	 */
102	this.toFullscreen = function(element, fullscreenID) {
103				  
104		  if(element.requestFullscreen) {
105		    element.requestFullscreen();
106		  } else if(element.mozRequestFullScreen) {
107		    element.mozRequestFullScreen();
108		  } else if(element.webkitRequestFullscreen) {
109		    element.webkitRequestFullscreen(); 
110		  } else if(element.msRequestFullscreen) {
111			    element.msRequestFullscreen(); 
112		  } else{
113			  return(false);
114		  }
115		  
116		  return(true);
117	}	
118	
119	
120	/**
121	 * exit full screen mode
122	 * return if operation success (or if fullscreen mode supported)
123	 */
124	this.exitFullscreen = function() {
125		  if(t.isFullScreen() == false)
126			  return(false);
127			  
128		  if(document.exitFullscreen) {
129		    document.exitFullscreen();
130
131		  } else if(document.cancelFullScreen) {
132			    document.cancelFullScreen();
133		    
134		  } else if(document.mozCancelFullScreen) {
135		    document.mozCancelFullScreen();
136		    
137		  } else if(document.webkitExitFullscreen) {
138		    document.webkitExitFullscreen();
139		    
140		  } else if(document.msExitFullscreen) {
141			    document.msExitFullscreen();
142			    
143		  }else{
144			  return(false);
145		  }
146		  
147		  return(true);
148	}	
149
150	/**
151	 * cross browser attach even function
152	 */
153	function addEvent(evnt, elem, func) {
154		   if (elem.addEventListener)  // W3C DOM
155		      elem.addEventListener(evnt,func,false);
156		   else if (elem.attachEvent) { // IE DOM
157		      elem.attachEvent("on"+evnt, func);
158		   }
159		   else { // No much to do
160		      elem[evnt] = func;
161		   }
162	}
163	
164	
165	/**
166	 * add fullscreen event to some function
167	 */
168	this.addFullScreenChangeEvent = function(func){
169		
170		if(document["webkitCancelFullScreen"])
171			addEvent("webkitfullscreenchange",document,func);
172		else if(document["msExitFullscreen"])
173			addEvent("MSFullscreenChange",document,func);
174		else if(document["mozCancelFullScreen"])
175			addEvent("mozfullscreenchange",document,func);
176		else
177			addEvent("fullscreenchange",document,func);
178	}
179	
180	
181	/**
182	 * destroy the full screen change event
183	 */
184	this.destroyFullScreenChangeEvent = function(){
185		
186		jQuery(document).unbind("fullscreenChange");
187		jQuery(document).unbind("mozfullscreenchange");
188		jQuery(document).unbind("webkitfullscreenchange");
189		jQuery(document).unbind("MSFullscreenChange");
190	}
191	
192	
193	/**
194	 * get the fullscreen element
195	 */
196	this.getFullScreenElement = function(){
197		
198		var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
199		
200		return(fullscreenElement);
201	}
202
203	/**
204	 * return if fullscreen enabled
205	 */
206	this.isFullScreen = function(){
207		
208		var isFullScreen = document.fullscreen || document.mozFullScreen || document.webkitIsFullScreen || document.msFullscreenElement;
209		
210		if(!isFullScreen)
211			isFullScreen = false;
212		else
213			isFullScreen = true;
214		
215		return(isFullScreen);
216	}
217	
218	
219	
220	this.z__________GET_PROPS___________ = function(){}
221	
222	/**
223	 * get browser prefix, can be empty if not detected.
224	 */
225	this.getBrowserPrefix = function(){
226		
227	   if(g_browserPrefix !== null)
228		   return g_browserPrefix;
229				
230	   var arrayOfPrefixes = ['webkit','Moz','ms','O'];
231	   
232	   var div = document.createElement("div");
233	   
234	   for(var index in arrayOfPrefixes){
235		   var prefix = arrayOfPrefixes[index];
236		   
237		   if(prefix+"Transform" in div.style){
238			   prefix = prefix.toLowerCase();
239			   g_browserPrefix = prefix;
240			   return(prefix);
241		   }
242	   }
243	   
244	   g_browserPrefix = "";
245	   return "";
246	}
247	
248	/**
249	 * get image inside parent data by image (find parent and size)
250	 * scaleMode: fit, down, fill, fitvert
251	 */
252	this.getImageInsideParentDataByImage = function(objImage, scaleMode, objPadding){
253		
254		var objParent = objImage.parent();
255		
256		var objOrgSize = t.getImageOriginalSize(objImage);
257		
258		var objData = t.getImageInsideParentData(objParent, objOrgSize.width, objOrgSize.height, scaleMode, objPadding);
259		
260		return(objData);
261	}
262	
263	
264	/**
265	 * get data of image inside parent
266	 * scaleMode: fit, down, fill, fitvert
267	 */
268	this.getImageInsideParentData = function(objParent, originalWidth, originalHeight, scaleMode, objPadding, maxWidth, maxHeight){
269		
270		if(!objPadding)
271			var objPadding = {};
272		
273		var objOutput = {};
274		
275		if(typeof maxWidth === "undefined")
276			var maxWidth = objParent.width();
277		
278		if(typeof maxHeight === "undefined")
279			var maxHeight = objParent.height();
280		
281		if(objPadding.padding_left)
282			maxWidth -= objPadding.padding_left;
283		
284		if(objPadding.padding_right)
285			maxWidth -= objPadding.padding_right;
286		
287		if(objPadding.padding_top)
288			maxHeight -= objPadding.padding_top;
289		
290		if(objPadding.padding_bottom)
291			maxHeight -= objPadding.padding_bottom;
292		
293		var imageWidth = null;
294		var imageHeight = "100%";
295		var imageTop = null;
296		var imageLeft = null;		
297		var style = "display:block;margin:0px auto;";
298		
299		if(originalWidth > 0 && originalHeight > 0){
300			
301			//get image size and position
302			
303			if(scaleMode == "down" && originalWidth < maxWidth && originalHeight < maxHeight){
304			
305				imageHeight = originalHeight;
306				imageWidth = originalWidth;
307				imageLeft = (maxWidth - imageWidth) / 2;
308				imageTop = (maxHeight - imageHeight) / 2;
309				
310			}else if(scaleMode == "fill"){
311				var ratio = originalWidth / originalHeight;
312				
313				imageHeight = maxHeight;
314				imageWidth = imageHeight * ratio;
315								
316				if(imageWidth < maxWidth){
317					imageWidth = maxWidth;
318					imageHeight = imageWidth / ratio;
319					
320					//center y position
321					imageLeft = 0;
322					imageTop = Math.round((imageHeight - maxHeight) / 2 * -1);
323				}else{	//center x position
324					imageTop = 0;
325					imageLeft = Math.round((imageWidth - maxWidth) / 2 * -1);
326				}
327								
328			}
329			else{		//fit to borders
330				var ratio = originalWidth / originalHeight;
331				imageHeight = maxHeight;
332				imageWidth = imageHeight * ratio;
333				imageTop = 0;
334				imageLeft = (maxWidth - imageWidth) / 2;
335				
336				if(scaleMode != "fitvert" && imageWidth > maxWidth){
337					imageWidth = maxWidth;
338					imageHeight = imageWidth / ratio;
339					imageLeft = 0;
340					imageTop = (maxHeight - imageHeight) / 2;
341				}
342			
343			}
344			
345			imageWidth = Math.floor(imageWidth);
346			imageHeight = Math.floor(imageHeight);
347			
348			imageTop = Math.floor(imageTop);
349			imageLeft = Math.floor(imageLeft);
350			
351			style="position:absolute;";
352		}
353		
354		//set padding
355		if(objPadding.padding_top)
356			imageTop += objPadding.padding_top;
357		
358		if(objPadding.padding_left)
359			imageLeft += objPadding.padding_left;
360		
361		objOutput.imageWidth = imageWidth;
362		objOutput.imageHeight = imageHeight;
363		objOutput.imageTop = imageTop;
364		objOutput.imageLeft = imageLeft;
365		objOutput.imageRight = imageLeft + imageWidth;
366		if(imageTop == 0 || imageHeight == "100%")
367			objOutput.imageBottom = null;
368		else
369			objOutput.imageBottom = imageTop + imageHeight;
370		
371		objOutput.style = style;
372		
373		return(objOutput);		
374	}
375	
376	
377	/**
378	 * get element center position inside parent 
379	 * even if the object bigger than the parent
380	 */
381	this.getElementCenterPosition = function(element, objPadding){
382		
383		var parent = element.parent();
384		var objSize = t.getElementSize(element);
385		var objSizeParent = t.getElementSize(parent);
386		
387		var parentWidth = objSizeParent.width;
388		var parentHeight = objSizeParent.height;
389		
390		if(objPadding && objPadding.padding_top !== undefined)
391			parentHeight -= objPadding.padding_top;
392		
393		if(objPadding && objPadding.padding_bottom !== undefined)
394			parentHeight -= objPadding.padding_bottom;
395		
396		if(objPadding && objPadding.padding_left !== undefined)
397			parentWidth -= objPadding.padding_left;
398		
399		if(objPadding && objPadding.padding_right !== undefined)
400			parentWidth -= objPadding.padding_right;
401		
402		
403		var output = {};
404		output.left = Math.round((parentWidth - objSize.width) / 2);
405		output.top = Math.round((parentHeight - objSize.height) / 2);
406		
407		if(objPadding && objPadding.padding_top !== undefined)
408			output.top += objPadding.padding_top;
409		
410		if(objPadding && objPadding.padding_left !== undefined)
411			output.left += objPadding.padding_left;
412		
413		
414		return(output);
415	}
416	
417	
418	/**
419	 * get the center of the element 
420	 * includeParent - including left / right related to the parent
421	 */
422	this.getElementCenterPoint = function(element, includeParent){
423		
424		if(!includeParent)
425			var includeParent = false;
426		
427		var objSize = t.getElementSize(element);
428		var output = {};
429		
430		output.x =  objSize.width / 2;
431		output.y =  objSize.height / 2;
432		
433		if(includeParent == true){
434			output.x += objSize.left;
435			output.y += objSize.top;
436		}
437		
438		output.x = Math.round(output.x);
439		output.y = Math.round(output.y);
440		
441		return(output);
442	}
443	
444	
445	/**
446	 * 
447	 * get mouse position from the event
448	 * optimised to every device
449	 */
450	this.getMousePosition = function(event, element){
451		
452		var output = {
453			pageX: 	event.pageX,
454			pageY: 	event.pageY,
455			clientX: 	event.clientX,
456			clientY: 	event.clientY
457		};
458		
459		if(event.originalEvent && event.originalEvent.touches && event.originalEvent.touches.length > 0){
460			output.pageX = event.originalEvent.touches[0].pageX;
461			output.pageY = event.originalEvent.touches[0].pageY;
462			output.clientX = event.originalEvent.touches[0].clientX;
463			output.clientY = event.originalEvent.touches[0].clientY;
464		}
465		
466		/**
467		 * get element's mouse position
468		 */
469		if(element){
470			var elementPos = element.offset();
471			output.mouseX = output.pageX - elementPos.left;
472			output.mouseY = output.pageY - elementPos.top;
473		}
474		
475		return(output);
476	}
477	
478	/**
479	 * get mouse element related point from page related point
480	 */
481	this.getMouseElementPoint = function(point, element){
482		
483		//rename the input and output
484		var newPoint = {x: point.pageX, y: point.pageY};
485		
486		var elementPoint = t.getElementLocalPoint(newPoint, element);
487		
488		return(elementPoint);
489	}
490	
491	
492	/**
493	 * get element local point from global point position
494	 */
495	this.getElementLocalPoint = function(point, element){
496		
497		var elementPoint = {};
498		var elementPos = element.offset();
499		
500		elementPoint.x = Math.round(point.x - elementPos.left);
501		elementPoint.y = Math.round(point.y - elementPos.top);
502		
503		return(elementPoint);
504	}
505
506	
507	/**
508	 * get image oritinal size
509	 * if originalWidth, originalHeight is set, just return them.
510	 */		
511	this.getImageOriginalSize = function(objImage, originalWidth, originalHeight){
512		
513		if(typeof originalWidth != "undefined" && typeof originalHeight != "undefined")
514			return({width:originalWidth, height:originalHeight});
515		
516		var htmlImage = objImage[0];
517		
518		if(typeof htmlImage == "undefined")
519			throw new Error("getImageOriginalSize error - Image not found");
520		
521		var output = {};
522		
523		if(typeof htmlImage.naturalWidth == "undefined"){
524
525			//check from cache
526			if(typeof objImage.data("naturalWidth") == "number"){
527				var output = {};
528				output.width = objImage.data("naturalWidth");
529				output.height = objImage.data("naturalHeight");
530				return(output);
531			}
532			
533		   //load new image
534		   var newImg = new Image();
535	       newImg.src = htmlImage.src;
536	        
537	       if (newImg.complete) {
538	        	output.width = newImg.width;
539	        	output.height = newImg.height;
540
541	        	//caching
542				objImage.data("naturalWidth", output.width);
543				objImage.data("naturalHeight", output.height);
544	        	return(output);
545	        	
546	       }
547	    
548	       return({width:0,height:0});
549		        
550		}else{
551			
552			output.width = htmlImage.naturalWidth;
553			output.height = htmlImage.naturalHeight;
554			
555			return(output);
556		}
557		
558	}
559
560	
561	/**
562	 * get current image ratio from original size
563	 */
564	this.getimageRatio = function(objImage){
565		
566		var originalSize = t.getImageOriginalSize(objImage);
567		var size = t.getElementSize(objImage);
568		var ratio = size.width / originalSize.width;
569		
570		return(ratio);
571	}
572	
573	/**
574	 * tells if the image fit the parent (smaller then the parent)
575	 */
576	this.isImageFitParent = function(objImage){
577		var objParent = objImage.parent();
578		var sizeImage = t.getElementSize(objImage);
579		var sizeParent = t.getElementSize(objParent);
580		
581		if(sizeImage.width <= sizeParent.width && sizeImage.height <= sizeParent.height)
582			return(true);
583		
584		return(false);
585	}
586	
587	/**
588	 * get size and position of some object
589	 */
590	this.getElementSize = function(element){
591
592		if(element === undefined){
593			throw new Error("Can't get size, empty element");
594		}
595				
596		var obj = element.position();
597				
598		obj.height = element.outerHeight();
599		obj.width = element.outerWidth();
600		
601		obj.left = Math.round(obj.left);
602		obj.top = Math.round(obj.top);
603		
604		obj.right = obj.left + obj.width;
605		obj.bottom = obj.top + obj.height;
606		
607		return(obj);		
608	}
609	
610	
611	
612	/**
613	 * return true if the element is bigger then it's parent
614	 */
615	this.isElementBiggerThenParent = function(element){
616		
617		var objParent = element.parent();
618		var objSizeElement = t.getElementSize(element);
619		var objSizeParent = t.getElementSize(objParent);
620		
621		if(objSizeElement.width > objSizeParent.width || objSizeElement.height > objSizeParent.height)
622			return(true);
623		
624		return(false);
625	}
626	
627	
628	/**
629	 * tells if the mouse point inside image
630	 * the mouse point is related to image pos
631	 */
632	this.isPointInsideElement = function(point, objSize){
633		
634		var isMouseXInside = (point.x >= 0 && point.x < objSize.width);
635		if(isMouseXInside == false)
636			return(false);
637		
638		var isMouseYInside = (point.y >= 0 && point.y < objSize.height);
639		if(isMouseYInside == false)
640			return(false);
641		
642		return(true);
643	}
644	
645	
646	/**
647	 * get element relative position according the parent
648	 * if the left / top is offset text (left , center, right / top, middle , bottom)
649	 * the element can be number size as well
650	 */
651	this.getElementRelativePos = function(element, pos, offset, objParent){
652		
653		if(!objParent)
654			var objParent = element.parent();
655		
656		if(typeof element == "number"){
657			var elementSize = {
658					width: element,
659					height: element
660			};
661		}else
662			var elementSize = t.getElementSize(element);
663		
664		var parentSize = t.getElementSize(objParent);
665		
666		
667		switch(pos){
668			case "top":
669			case "left":
670				pos = 0;
671				if(offset)
672					pos += offset;
673			break;
674			case "center":
675				pos = Math.round((parentSize.width - elementSize.width) / 2);
676				if(offset)
677					pos += offset;
678				
679			break;
680			case "right":
681				pos = parentSize.width - elementSize.width;
682				if(offset)
683					pos -= offset;
684			break;
685			case "middle":
686				pos = Math.round((parentSize.height - elementSize.height) / 2);
687				if(offset)
688					pos += offset;
689			break;
690			case "bottom":
691				pos = parentSize.height - elementSize.height;
692				if(offset)
693					pos -= offset;
694			break;
695		}
696		
697		return(pos);
698	}
699	
700		
701	
702	this.z_________SET_ELEMENT_PROPS_______ = function(){}
703		
704	
705	/**
706	 * 
707	 * zoom image inside parent
708	 * the mouse point is page offset position, can be null
709	 * return true if zoomed and false if not zoomed
710	 */
711	this.zoomImageInsideParent = function(objImage, zoomIn, step, point, scaleMode, maxZoomRatio, objPadding){
712		
713		if(!step)
714			var step = 1.2;
715		
716		if(!scaleMode)
717			var scaleMode = "fit";
718		
719		var zoomRatio = step;
720		
721		var objParent = objImage.parent();		
722		
723		var objSize = t.getElementSize(objImage);
724		var objOriginalSize = t.getImageOriginalSize(objImage);
725		
726		
727		var isMouseInside = false;
728		var newHeight,newWidth, panX = 0, panY = 0, newX, newY,panOrientX = 0, panOrientY = 0;
729		
730		if(!point){
731			isMouseInside = false;
732		}else{
733			var pointImg = t.getMouseElementPoint(point, objImage);				
734			isMouseInside = t.isPointInsideElement(pointImg, objSize);
735			
736			//if mouse point outside image, set orient to image center
737			panOrientX = pointImg.x;
738			panOrientY = pointImg.y;
739		}
740				
741		if(isMouseInside == false){
742			var imgCenterPoint = t.getElementCenterPoint(objImage);
743			panOrientX = imgCenterPoint.x;
744			panOrientY = imgCenterPoint.y;
745		}
746						
747		//zoom:
748		if(zoomIn == true){		//zoom in
749			
750			newHeight = objSize.height * zoomRatio;
751			newWidth =  objSize.width * zoomRatio;
752			
753			if(panOrientX != 0)
754				panX = -(panOrientX * zoomRatio - panOrientX);
755			
756			if(panOrientY != 0)
757				panY = -(panOrientY * zoomRatio - panOrientY);
758			
759			
760		}else{		//zoom out
761			
762			newHeight = objSize.height / zoomRatio;
763			newWidth =  objSize.width / zoomRatio;
764			
765			var objScaleData = t.getImageInsideParentData(objParent, objOriginalSize.width, objOriginalSize.height, scaleMode, objPadding);
766			
767			//go back to original size
768			if(newWidth < objScaleData.imageWidth){
769				
770				t.scaleImageFitParent(objImage, objOriginalSize.width, objOriginalSize.height, scaleMode, objPadding);
771				return(true);
772			}
773			
774			if(isMouseInside == true){
775				if(panOrientX != 0)
776					panX = -(panOrientX / zoomRatio - panOrientX);
777				
778				if(panOrientY != 0)			
779					panY = -(panOrientY / zoomRatio - panOrientY);
780			}
781			
782		}
783		
784		//check max zoom ratio, ix exeeded, abort
785		if(maxZoomRatio){
786			var expectedZoomRatio = 1;
787			if(objOriginalSize.width != 0)
788				expectedZoomRatio = newWidth / objOriginalSize.width;
789			
790			if(expectedZoomRatio > maxZoomRatio)
791				return(false);
792		}
793		
794		//resize the element
795		t.setElementSize(objImage, newWidth, newHeight);
796		
797		//set position:
798		
799		//if zoom out and mouse point not inside image, 
800		//get the image to center
801		if(zoomIn == false && isMouseInside == false){
802			var posCenter = t.getElementCenterPosition(objImage);
803			newX = posCenter.left;
804			newY = posCenter.top;
805		}else{
806			
807			newX = objSize.left + panX;
808			newY = objSize.top + panY;
809		}
810		
811		t.placeElement(objImage, newX, newY);
812		
813		return(true);
814	}
815	
816
817	
818	/**
819	 * place some element to some position
820	 * if the left / top is offset text (left , center, right / top, middle , bottom)
821	 * then put it in parent by the offset.
822	 */
823	this.placeElement = function(element, left, top, offsetLeft, offsetTop, objParent){
824		
825		
826		if(jQuery.isNumeric(left) == false || jQuery.isNumeric(top) == false){
827			
828			if(!objParent)
829				var objParent = element.parent();
830			
831			var elementSize = t.getElementSize(element);
832			var parentSize = t.getElementSize(objParent);
833		}
834		
835		//select left position
836		if(jQuery.isNumeric(left) == false){
837			
838			switch(left){
839				case "left":
840					left = 0;
841					if(offsetLeft)
842						left += offsetLeft;
843				break;
844				case "center":
845					left = Math.round((parentSize.width - elementSize.width) / 2);
846					if(offsetLeft)
847						left += offsetLeft;
848				break;
849				case "right":
850					left = parentSize.width - elementSize.width;
851					if(offsetLeft)
852						left -= offsetLeft;
853				break;
854			}
855		}
856		
857		//select top position
858		if(jQuery.isNumeric(top) == false){
859			
860			switch(top){
861				case "top":
862					top = 0;
863					if(offsetTop)
864						top += offsetTop;
865				break;
866				case "middle":
867				case "center":
868					top = Math.round((parentSize.height - elementSize.height) / 2);
869					if(offsetTop)
870						top += offsetTop;
871				break;
872				case "bottom":
873					top = parentSize.height - elementSize.height;
874					if(offsetTop)
875						top -= offsetTop;
876				break;
877			}
878			
879		}
880		
881		
882		var objCss = {
883				"position":"absolute",
884				"margin":"0px"				
885		};
886		
887		if(left !== null)
888			objCss.left = left;
889		
890		if(top !== null)
891			objCss.top = top;
892				
893		element.css(objCss);		
894	}
895	
896	
897	/**
898	 * place element inside parent center.
899	 * the element should be absolute position
900	 */
901	this.placeElementInParentCenter = function(element){
902				
903		t.placeElement(element, "center", "middle");
904	}
905	
906	
907	/**
908	 * set element size and position
909	 */
910	this.setElementSizeAndPosition = function(element,left,top,width,height){
911		
912		var objCss = {
913			"width":width+"px",
914			"height":height+"px",
915			"left":left+"px",
916			"top":top+"px",
917			"position":"absolute",
918			"margin":"0px"
919		}
920		
921		element.css(objCss);
922	}
923	
924	/**
925	 * set widht and height of the element
926	 */
927	this.setElementSize = function(element, width, height){
928		
929	    var objCss = {
930			"width":width+"px"
931		}
932	    
933	    if(height !== null && typeof height != "undefined")
934	    	objCss["height"] = height+"px"
935	    
936		element.css(objCss);	
937	}
938	
939	
940	/**
941	 * clone element size and position
942	 */
943	this.cloneElementSizeAndPos = function(objSource, objTarget, isOuter, offsetX, offsetY){
944		
945		var objSize = objSource.position();
946		
947		if(objSize == undefined){
948			throw new Error("Can't get size, empty element");
949		}
950		
951		if(isOuter === true){
952			objSize.height = objSource.outerHeight();
953			objSize.width = objSource.outerWidth();
954		}else{
955			objSize.height = objSource.height();
956			objSize.width = objSource.width();
957		}
958		
959		objSize.left = Math.round(objSize.left);
960		objSize.top = Math.round(objSize.top);
961		
962		if(offsetX)
963			objSize.left += offsetX;
964		
965		if(offsetY)
966			objSize.top += offsetY;
967		
968		t.setElementSizeAndPosition(objTarget, objSize.left, objSize.top, objSize.width, objSize.height);
969	}
970
971	
972	/**
973	 * place image inside parent, scale it by the options
974	 * and scale it to fit the parent.
975	 * scaleMode: fit, down, fill
976	 */
977	this.placeImageInsideParent = function(urlImage, objParent, originalWidth, originalHeight, scaleMode, objPadding){
978		var obj = t.getImageInsideParentData(objParent, originalWidth, originalHeight, scaleMode, objPadding);
979		
980		//set html image:
981		var htmlImage = "<img";
982		
983		if(obj.imageWidth !== null){
984			htmlImage += " width = '" + obj.imageWidth + "'";
985			obj.style += "width:" + obj.imageWidth + ";";
986		}
987		
988		if(obj.imageHeight != null){
989			
990			if(obj.imageHeight == "100%"){
991				htmlImage += " height = '" + obj.imageHeight+"'";
992				obj.style += "height:" + obj.imageHeight+";";				
993			}else{
994				htmlImage += " height = '" + obj.imageHeight + "'";
995				obj.style += "height:" + obj.imageHeight + "px;";				
996			}
997			
998		}
999		
1000		if(obj.imageTop !== null)
1001			obj.style += "top:"+obj.imageTop+"px;";
1002		
1003		if(obj.imageLeft !== null){
1004			obj.style += "left:"+obj.imageLeft+"px;";
1005		}
1006		
1007		urlImage = t.escapeDoubleSlash(urlImage);
1008		
1009		htmlImage += " style='"+obj.style+"'";
1010		htmlImage += " src=\""+urlImage+"\"";
1011		htmlImage += ">";
1012				
1013		objParent.html(htmlImage);
1014		
1015		//return the image just created
1016		var objImage = objParent.children("img");
1017		
1018		return(objImage);
1019	}
1020	
1021	
1022	/**
1023	 * scale image to fit parent, and place it into parent
1024	 * parent can be width , height, or object
1025	 */	
1026	this.scaleImageCoverParent = function(objImage, objParent, pHeight){
1027		
1028		if(typeof objParent == "number"){
1029			var parentWidth = objParent;
1030			var parentHeight = pHeight;
1031		}else{
1032			var parentWidth = objParent.outerWidth();
1033			var parentHeight = objParent.outerHeight();
1034		}
1035		
1036		var objOriginalSize = t.getImageOriginalSize(objImage);
1037
1038		var imageWidth = objOriginalSize.width;
1039		var imageHeight = objOriginalSize.height;
1040		
1041		var ratio = imageWidth / imageHeight;
1042		
1043		var fitHeight = parentHeight;
1044		var fitWidth = fitHeight * ratio;
1045		var posy = 0, posx = 0;
1046		
1047		if(fitWidth < parentWidth){
1048			fitWidth = parentWidth;
1049			fitHeight = fitWidth / ratio;
1050			
1051			//center y position
1052			posx = 0;
1053			posy = Math.round((fitHeight - parentHeight) / 2 * -1);
1054		}else{	//center x position
1055			posy = 0;
1056			posx = Math.round((fitWidth - parentWidth) / 2 * -1);
1057		}
1058		
1059		fitWidth = Math.round(fitWidth);
1060		fitHeight = Math.round(fitHeight);
1061		
1062		objImage.css({"width":fitWidth+"px",
1063					  "height":fitHeight+"px",
1064					  "left":posx+"px",
1065					  "top":posy+"px"});		
1066	}
1067
1068
1069	
1070	
1071	/**
1072	 * resize image to fit the parent, scale it by the options
1073	 * scaleMode: fit, down, fill
1074	 */
1075	this.scaleImageFitParent = function(objImage, originalWidth, originalHeight, scaleMode, objPadding){
1076		
1077		var objParent = objImage.parent();
1078		
1079		var obj = t.getImageInsideParentData(objParent, originalWidth, originalHeight, scaleMode, objPadding);
1080		
1081		var updateCss = false;
1082		
1083		var objCss = {};
1084		
1085		if(obj.imageWidth !== null){
1086			updateCss = true
1087			objImage.removeAttr("width");
1088			objCss["width"] = obj.imageWidth+"px";
1089		}
1090		
1091		if(obj.imageHeight != null){
1092			updateCss = true
1093			objImage.removeAttr("height");
1094			objCss["height"] = obj.imageHeight+"px";
1095		}
1096		
1097		if(obj.imageTop !== null){
1098			updateCss = true;			
1099			objCss.top = obj.imageTop+"px";
1100		}
1101		
1102		if(obj.imageLeft !== null){
1103			updateCss = true;		
1104			objCss.left = obj.imageLeft+"px";
1105		}
1106			
1107		if(updateCss == true){
1108			
1109			objCss.position = "absolute";
1110			objCss.margin = "0px 0px";
1111			
1112			objImage.css(objCss);			
1113		}
1114		
1115		
1116		return(obj);
1117	}
1118	
1119	
1120	/**
1121	 * scale image by height
1122	 */
1123	this.scaleImageByHeight = function(objImage, height, originalWidth, originalHeight){
1124		
1125		var objOriginalSize = t.getImageOriginalSize(objImage, originalWidth, originalHeight);
1126		
1127		var ratio = objOriginalSize.width / objOriginalSize.height;
1128		var width = Math.round(height * ratio);
1129		height = Math.round(height);
1130		
1131		t.setElementSize(objImage, width, height);
1132	}
1133
1134	
1135	/**
1136	 * scale image by height
1137	 */
1138	this.scaleImageByWidth = function(objImage, width, originalWidth, originalHeight){
1139		
1140		var objOriginalSize = t.getImageOriginalSize(objImage, originalWidth, originalHeight);
1141		
1142		var ratio = objOriginalSize.width / objOriginalSize.height;
1143		
1144		var height = Math.round(width / ratio);
1145		width = Math.round(width);
1146		
1147		t.setElementSize(objImage, width, height);
1148		
1149	}
1150	
1151	
1152	/**
1153	 * scale image to exact size in parent, by setting image size and padding
1154	 */
1155	this.scaleImageExactSizeInParent = function(objImage, originalWidth, originalHeight, exactWidth, exactHeight, scaleMode){
1156		
1157		var objParent = objImage.parent();
1158		var parentSize = t.getElementSize(objParent);
1159		
1160		if(parentSize.width < exactWidth)
1161			exactWidth = parentSize.width;
1162		
1163		if(parentSize.height < exactHeight)
1164			exactHeight = parentSize.height;
1165		
1166		var obj = t.getImageInsideParentData(null, originalWidth, originalHeight, scaleMode, null, exactWidth, exactHeight);
1167		
1168		var imageWidth = exactWidth;
1169		var imageHeight = exactHeight;
1170		
1171		var paddingLeft = obj.imageLeft;
1172		var paddingRight = obj.imageLeft;
1173		var paddingTop = obj.imageTop;
1174		var paddingBottom = obj.imageTop;
1175		var imageLeft = Math.round((parentSize.width - exactWidth) / 2);
1176		var imageTop = Math.round((parentSize.height - exactHeight) / 2);
1177		
1178		var totalWidth = obj.imageWidth + paddingLeft + paddingRight;
1179		var diff = exactWidth - totalWidth;
1180		if(diff != 0)
1181			paddingRight += diff;
1182		
1183		var totalHeight = obj.imageHeight + paddingTop + paddingBottom;
1184		
1185		var diff = exactHeight - totalHeight;
1186		if(diff != 0)
1187			paddingBottom += diff;
1188		
1189		//update css:
1190		objImage.removeAttr("width");
1191		objImage.removeAttr("height");
1192
1193		var objCss = {
1194				position: "absolute",
1195				margin: "0px 0px"
1196		};
1197		
1198		objCss["width"] = imageWidth+"px";
1199		objCss["height"] = imageHeight+"px";
1200		objCss["left"] = imageLeft+"px";
1201		objCss["top"] = imageTop+"px";
1202		objCss["padding-left"] = paddingLeft+"px";
1203		objCss["padding-top"] = paddingTop+"px";
1204		objCss["padding-right"] = paddingRight+"px";
1205		objCss["padding-bottom"] = paddingBottom+"px";
1206				
1207		objImage.css(objCss);
1208		
1209		//return size object
1210		
1211		var objReturn = {};
1212		objReturn["imageWidth"] = imageWidth;
1213		objReturn["imageHeight"] = imageHeight;
1214		return(objReturn);
1215	}
1216	
1217	
1218	/**
1219	 * show some element and make opacity:1
1220	 */
1221	this.showElement = function(element, element2, element3){
1222		
1223		element.show().fadeTo(0,1);
1224		
1225		if(element2)
1226			element2.show().fadeTo(0,1);
1227			
1228		if(element3)
1229				element3.show().fadeTo(0,1);
1230			
1231	}
1232	
1233		
1234	this.z_________GALLERY_RELATED_FUNCTIONS_______ = function(){}
1235	
1236	/**
1237	 * disable button
1238	 */
1239	this.disableButton = function(objButton, className){
1240		if(!className)
1241			var className = "ug-button-disabled";
1242		
1243		if(t.isButtonDisabled(objButton, className) == false)		
1244			objButton.addClass(className);		
1245	}
1246
1247	
1248	/**
1249	 * convert custom prefix options
1250	 * prefix - the prefix.
1251	 * base - after the prefix text. example lightbox_slider_option (lightbox - prefix, slider - base)
1252	 */
1253	this.convertCustomPrefixOptions = function(objOptions, prefix, base){
1254			
1255		if(!prefix)
1256			return(objOptions);
1257		
1258		var modifiedOptions = {};
1259		
1260		jQuery.each(objOptions, function(key, option){
1261			
1262			if(key.indexOf(prefix + "_"+base+"_") === 0){
1263				var newKey = key.replace(prefix+"_"+base+"_", base+"_");
1264				modifiedOptions[newKey] = option;
1265			}else{
1266				modifiedOptions[key] = option;
1267			}
1268			
1269		});
1270		
1271		return(modifiedOptions);
1272	}
1273	
1274	
1275	/**
1276	 * enable button
1277	 */
1278	this.enableButton = function(objButton, className){
1279		if(!className)
1280			var className = "ug-button-disabled";
1281		
1282		if(t.isButtonDisabled(objButton, className) == true)		
1283			objButton.removeClass(className);
1284	}
1285	
1286	
1287	/**
1288	 * check if some buggon disabled
1289	 */
1290	this.isButtonDisabled = function(objButton, className){
1291		if(!className)
1292			var className = "ug-button-disabled";
1293		
1294		if(objButton.hasClass(className))
1295			return(true);
1296		
1297		return(false);
1298	}
1299	
1300	
1301
1302	this.z_________MATH_FUNCTIONS_______ = function(){}
1303	
1304	/**
1305	 * 
1306	 * normalize the value for readable "human" setting value.
1307	 */
1308	this.normalizeSetting = function(realMin, realMax, settingMin, settingMax, value, fixBounds){
1309		if(!fixBounds)
1310			var fixBounds = false;
1311		
1312		var ratio = (value - settingMin)  / (settingMax - settingMin);
1313		value = realMin + (realMax - realMin) * ratio;
1314		
1315		if(fixBounds == true){
1316			if(value < realMin)
1317				value = realMin;
1318			
1319			if(value > realMax)
1320				value = realMax;
1321		}
1322		
1323		return(value);
1324	}
1325
1326	
1327	/**
1328	 * 
1329	 * get "real" setting from normalized setting
1330	 */
1331	this.getNormalizedValue = function(realMin, realMax, settingMin, settingMax, realValue){
1332		
1333		var ratio = (realValue - realMin)  / (realMax - realMin);
1334		realValue = realMin + (settingMax - settingMin) * ratio;
1335		
1336		return(realValue);
1337	}
1338	
1339	
1340	/**
1341	 * get distance between 2 points
1342	 */
1343	this.getDistance = function(x1,y1,x2,y2) {
1344		
1345		var distance = Math.round(Math.sqrt(Math.abs(((x2-x1)*(x2-x1)) + ((y2-y1)*(y2-y1)))));
1346		
1347		return distance;
1348	}
1349	
1350	
1351	/**
1352	 * get center point of the 2 points
1353	 */
1354	this.getMiddlePoint = function(x1,y1,x2,y2){
1355		var output = {}
1356		output.x = x1 + Math.round((x2 - x1) / 2);
1357		output.y = y1 + Math.round((y2 - y1) / 2);
1358		
1359		return(output);
1360	}
1361	
1362	
1363	/**
1364	 * get number of items in space width gap
1365	 * even item sizes
1366	 * by lowest
1367	 */
1368	this.getNumItemsInSpace = function(spaceSize, itemsSize, gapSize){
1369		var numItems = Math.floor((spaceSize + gapSize) / (itemsSize + gapSize));
1370		return(numItems);
1371	}
1372
1373	/**
1374	 * get number of items in space width gap
1375	 * even item sizes
1376	 * by Math.round
1377	 */
1378	this.getNumItemsInSpaceRound = function(spaceSize, itemsSize, gapSize){
1379		var numItems = Math.round((spaceSize + gapSize) / (itemsSize + gapSize));
1380		return(numItems);
1381	}
1382
1383	/**
1384	 * get space (width in carousel for example) by num items, item size, and gap size
1385	 */
1386	this.getSpaceByNumItems = function(numItems, itemSize, gapSize){
1387		var space = numItems * itemSize + (numItems-1) * gapSize;
1388		return(space);
1389	}
1390	
1391
1392	/**
1393	 * get item size by space and gap
1394	 */
1395	this.getItemSizeInSpace = function(spaceSize, numItems, gapSize){
1396		var itemSize = Math.floor((spaceSize - (numItems-1) * gapSize) / numItems);
1397		
1398		return(itemSize);
1399	}
1400	
1401	
1402	/**
1403	 * get column x pos with even column sizes, start from 0
1404	 */
1405	this.getColX = function(col, colWidth, colGap){
1406		
1407		var posx = col * (colWidth + colGap);
1408		
1409		return posx;
1410	}
1411	
1412
1413	/**
1414	 * get column number by index
1415	 */
1416	this.getColByIndex = function(numCols, index){
1417		var col = index % numCols;
1418		return(col);
1419	}
1420	
1421	
1422	/**
1423	 * get col and row by index
1424	 */
1425	this.getColRowByIndex = function(index, numCols){
1426		
1427		var row = Math.floor(index / numCols);
1428		var col = Math.floor(index % numCols);
1429		
1430		return({col:col,row:row});
1431	}
1432	
1433	
1434	/**
1435	 * get index by row, col, numcols
1436	 */
1437	this.getIndexByRowCol = function(row, col, numCols){
1438		
1439		if(row < 0)
1440			return(-1);
1441		
1442		if(col < 0)
1443			return(-1);
1444		
1445		var index = row * numCols + col;
1446		return(index);
1447	}
1448	
1449	/**
1450	 * get previous row item in the same column
1451	 */
1452	this.getPrevRowSameColIndex = function(index, numCols){
1453		var obj = t.getColRowByIndex(index, numCols);
1454		var prevIndex = t.getIndexByRowCol(obj.row-1, obj.col, numCols);
1455		return(prevIndex);
1456	}
1457	
1458	/**
1459	 * get next row item in the same column
1460	 */
1461	this.getNextRowSameColIndex = function(index, numCols){
1462		var obj = t.getColRowByIndex(index, numCols);
1463		var nextIndex = t.getIndexByRowCol(obj.row+1, obj.col, numCols);
1464		return(nextIndex);
1465	}
1466	
1467	
1468	this.z_________DATA_FUNCTIONS_______ = function(){}
1469	
1470	
1471	/**
1472	 * set data value
1473	 */
1474	this.setGlobalData = function(key, value){
1475		
1476		jQuery.data(document.body, key, value);
1477		
1478	}
1479	
1480	/**
1481	 * get global data
1482	 */
1483	this.getGlobalData = function(key){
1484		
1485		var value = jQuery.data(document.body, key);
1486		
1487		return(value);
1488	}
1489	
1490	this.z_________EVENT_DATA_FUNCTIONS_______ = function(){}
1491
1492	
1493	/**
1494	 * handle scroll top, return if scroll mode or not
1495	 */
1496	this.handleScrollTop = function(storedEventID){
1497		
1498		if(t.isTouchDevice() == false)
1499			return(null);
1500		
1501		var objData = t.getStoredEventData(storedEventID);
1502		
1503		var horPass = 15;
1504		var vertPass = 15;
1505		
1506		//check if need to set some movement
1507		if(objData.scrollDir === null){
1508			
1509			if(Math.abs(objData.diffMouseX) > horPass)
1510				objData.scrollDir = "hor";
1511			else
1512				if(Math.abs(objData.diffMouseY) > vertPass && Math.abs(objData.diffMouseY) > Math.abs(objData.diffMouseX) ){
1513					objData.scrollDir = "vert";
1514					objData.scrollStartY = objData.lastMouseClientY;
1515					objData.scrollOrigin = jQuery(document).scrollTop();
1516					
1517					g_temp.dataCache[storedEventID].scrollStartY = objData.lastMouseClientY;
1518					g_temp.dataCache[storedEventID].scrollOrigin = objData.scrollOrigin;
1519				}
1520			
1521			//update scrollDir
1522			g_temp.dataCache[storedEventID].scrollDir = objData.scrollDir;
1523		}
1524				
1525		if(objData.scrollDir !== "vert")
1526			return(objData.scrollDir);
1527		
1528		
1529		var currentScroll = jQuery(document).scrollTop();
1530		
1531		var scrollPos = objData.scrollOrigin - (objData.lastMouseClientY - objData.scrollStartY);
1532		
1533		if(scrollPos >= 0)
1534			jQuery(document).scrollTop(scrollPos);
1535		
1536		return(objData.scrollDir);
1537	}
1538
1539	
1540	/**
1541	 * return true / false if was vertical scrolling
1542	 */
1543	this.wasVerticalScroll = function(storedEventID){
1544		var objData = t.getStoredEventData(storedEventID);
1545		
1546		if(objData.scrollDir === "vert")
1547			return(true);
1548		
1549		return(false);
1550	}
1551	
1552	
1553	/**
1554	 * store event data
1555	 */
1556	this.storeEventData = function(event, id, addData){
1557				
1558		var mousePos = t.getMousePosition(event);
1559		var time = jQuery.now();
1560		
1561		var obj = {
1562				startTime: time,
1563				lastTime: time,
1564				startMouseX: mousePos.pageX,
1565				startMouseY: mousePos.pageY,
1566				lastMouseX: mousePos.pageX,
1567				lastMouseY: mousePos.pageY,
1568				
1569				startMouseClientY: mousePos.clientY,
1570				lastMouseClientY: mousePos.clientY,
1571				
1572				scrollTop: jQuery(document).scrollTop(),
1573				scrollDir: null
1574		};
1575		
1576		if(addData)
1577			obj = jQuery.extend(obj, addData);
1578		
1579		g_temp.dataCache[id] = obj;
1580		
1581	}
1582	
1583	
1584	/**
1585	 * update event data with last position
1586	 */
1587	this.updateStoredEventData = function(event, id, addData){
1588		
1589		if(!g_temp.dataCache[id])
1590			throw new Error("updateEventData error: must have stored cache object");
1591		
1592		var obj = g_temp.dataCache[id];
1593		
1594		var mousePos = t.getMousePosition(event);
1595		obj.lastTime = jQuery.now();
1596		
1597		if(mousePos.pageX !== undefined){
1598			obj.lastMouseX = mousePos.pageX;
1599			obj.lastMouseY = mousePos.pageY;
1600			obj.lastMouseClientY = mousePos.clientY;
1601		}
1602		
1603		if(addData)
1604			obj = jQuery.extend(obj, addData);
1605		
1606		g_temp.dataCache[id] = obj;
1607	}
1608	
1609	/**
1610	 * get stored event data
1611	 */
1612	this.getStoredEventData = function(id, isVertical){
1613		if(!g_temp.dataCache[id])
1614			throw new Error("updateEventData error: must have stored cache object");
1615		
1616		var obj = g_temp.dataCache[id];
1617		
1618		obj.diffMouseX = obj.lastMouseX - obj.startMouseX;
1619		obj.diffMouseY = obj.lastMouseY - obj.startMouseY;
1620		
1621		obj.diffMouseClientY = obj.lastMouseClientY - obj.startMouseClientY;
1622		
1623		obj.diffTime = obj.lastTime - obj.startTime;
1624		
1625		//get mouse position according orientation
1626		if(isVertical === true){
1627			obj.startMousePos = obj.lastMouseY;
1628			obj.lastMousePos = obj.lastMouseY;
1629			obj.diffMousePos = obj.diffMouseY;
1630		}else{
1631			obj.startMousePos = obj.lastMouseX;
1632			obj.lastMousePos = obj.lastMouseX;
1633			obj.diffMousePos = obj.diffMouseX;			
1634		}
1635		
1636		return(obj);
1637	}
1638	
1639	/**
1640	 * return if click event approved according the done motion
1641	 */
1642	this.isApproveStoredEventClick = function(id, isVertical){
1643		
1644		if(!g_temp.dataCache[id])
1645			return(true);
1646		
1647		var objData = t.getStoredEventData(id, isVertical);
1648		
1649		var passedDistanceAbs = Math.abs(objData.diffMousePos);
1650		
1651		if(objData.diffTime > 400)
1652			return(false);
1653		
1654		if(passedDistanceAbs > 30)
1655			return(false);
1656		
1657		return(true);
1658		
1659	}
1660	
1661	
1662	/**
1663	 * clear stored event data
1664	 */
1665	this.clearStoredEventData = function(id){
1666		g_temp.dataCache[id] = null;
1667	}
1668
1669	this.z_________CHECK_SUPPORT_FUNCTIONS_______ = function(){}
1670	
1671	
1672	
1673	/**
1674	 * is canvas exists in the browser
1675	 */
1676	this.isCanvasExists = function(){
1677		
1678		var canvas = jQuery('<canvas width="500" height="500" > </canvas>')[0];
1679		
1680		if(typeof canvas.getContext == "function")
1681			return(true);
1682		
1683		return(false);
1684	}
1685	
1686	/**
1687	 * tells if vertical scrollbar exists
1688	 */
1689	this.isScrollbarExists = function(){
1690		var hasScrollbar = window.innerWidth > document.documentElement.clientWidth;
1691		return(hasScrollbar);
1692	}
1693	
1694	/**
1695	 * check if this device are touch enabled
1696	 */
1697	this.isTouchDevice = function(){
1698		
1699		  //get from cache
1700		  if(g_temp.isTouchDevice !== -1)
1701			  return(g_temp.isTouchDevice);
1702		  
1703		  try{ 
1704			  document.createEvent("TouchEvent"); 
1705			  g_temp.isTouchDevice = true; 
1706		  }
1707		  catch(e){ 
1708			  g_temp.isTouchDevice = false; 
1709		  }
1710		  
1711		  return(g_temp.isTouchDevice);
1712	}
1713	
1714	
1715	
1716	/**
1717	 * check if 
1718	 */
1719	this.isRgbaSupported = function(){
1720		
1721		if(g_temp.isRgbaSupported !== -1)
1722			return(g_temp.isRgbaSupported);
1723		
1724		var scriptElement = document.getElementsByTagName('script')[0];
1725		var prevColor = scriptElement.style.color;
1726		try {
1727			scriptElement.style.color = 'rgba(1,5,13,0.44)';
1728		} catch(e) {}
1729		var result = scriptElement.style.color != prevColor;
1730		scriptElement.style.color = prevColor;
1731		
1732		g_temp.isRgbaSupported = result;
1733		
1734		return result;
1735	}
1736	
1737	this.z_________GENERAL_FUNCTIONS_______ = function(){}
1738	
1739	
1740	/**
1741	 * check if current jquery version is more then minimal version
1742	 * version can be "1.8.0" for example
1743	 */
1744	this.checkMinJqueryVersion = function(version){
1745
1746	   var arrCurrent = jQuery.fn.jquery.split('.');
1747       var arrMin = version.split('.');
1748	  
1749	  for (var i=0, len=arrCurrent.length; i<len; i++) {
1750		  
1751		  var numCurrent = parseInt(arrCurrent[i]);
1752	      var numMin = parseInt(arrMin[i]);
1753
1754	      if(typeof arrMin[i] == "undefined")
1755	    	  return(true);
1756	      
1757	      if(numMin > numCurrent)
1758	    	  return(false);
1759	      
1760	      if(numCurrent > numMin)
1761	    	  return(true);
1762	  }
1763	  
1764	  
1765	  //if all equal then all ok
1766	  return true;
1767	}
1768
1769	
1770	/**
1771	 * get css size parameter, like width. if % given, leave it, if number without px - add px.
1772	 */
1773	this.getCssSizeParam = function(sizeParam){
1774		if(jQuery.isNumeric(sizeParam))
1775			return(sizeParam + "px");
1776			
1777		return(sizeParam);
1778	}
1779	
1780	/**
1781	 * convert hex color to rgb color
1782	 */
1783	this.convertHexToRGB = function(hexInput, opacity){
1784	    
1785		var hex = hexInput.replace('#','');
1786	    if(hex === hexInput)
1787	    	return(hexInput);
1788	    
1789	    r = parseInt(hex.substring(0,2), 16);
1790	    g = parseInt(hex.substring(2,4), 16);
1791	    b = parseInt(hex.substring(4,6), 16);
1792	    result = 'rgba('+r+','+g+','+b+','+opacity+')';
1793	    return result;
1794	}	
1795	
1796	/**
1797	 * get timestamp to string
1798	 */
1799	this.timestampToString = function(stamp){
1800		
1801		var d = new Date(stamp);
1802		var str = d.getDate() + "/" + d.getMonth();
1803		str += " " + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + ":" + d.getMilliseconds();
1804		
1805		return(str);
1806	}
1807	
1808	/**
1809	 * get touches array (if exists) from the event
1810	 */
1811	this.getArrTouches = function(event){
1812		
1813		var arrTouches = [];
1814				
1815		if(event.originalEvent && event.originalEvent.touches && event.originalEvent.touches.length > 0){			
1816			arrTouches = event.originalEvent.touches;
1817		}
1818		
1819		return(arrTouches);
1820	}
1821	
1822	/**
1823	 * extract touch positions from arrTouches
1824	 */
1825	this.getArrTouchPositions = function(arrTouches){
1826		
1827		var arrOutput = [];
1828		
1829		for(var i=0;i<arrTouches.length;i++){
1830			
1831			var point = {
1832				pageX:arrTouches[i].pageX,
1833				pageY:arrTouches[i].pageY
1834			};
1835			
1836			arrOutput.push(point);
1837		}
1838		
1839		return(arrOutput);
1840	}
1841	
1842	
1843	/**
1844	 * start time debug
1845	 */
1846	this.startTimeDebug = function(){
1847		g_temp.starTime = jQuery.now();
1848	}
1849	
1850	/**
1851	 * show time debug
1852	 */
1853	this.showTimeDebug = function(){
1854		
1855		var endTime = jQuery.now();
1856		var diffTime = endTime - g_temp.starTime;
1857		
1858		debugLine({"Time Passed": diffTime},true);
1859	}
1860	
1861		
1862	/**
1863	 * put progress indicator to some parent by type
1864	 * return the progress indicator object
1865	 */
1866	this.initProgressIndicator = function(type, options, objParent){
1867		
1868		//check canvas compatability
1869		if(type != "bar" && t.isCanvasExists() == false)
1870			type = "bar";
1871		
1872		//put the progress indicator
1873		switch(type){
1874			case "bar":
1875				var g_objProgress = new UGProgressBar();		
1876				g_objProgress.putHidden(objParent, options);
1877			break;
1878			default:
1879			case "pie":
1880				var g_objProgress = new UGProgressPie();		
1881				g_objProgress.putHidden(objParent, options);
1882			break;			
1883			case "pie2":
1884				options.type_fill = true;
1885				
1886				var g_objProgress = new UGProgressPie();				
1887				g_objProgress.putHidden(objParent, options);
1888			break;			
1889		}
1890		
1891		return(g_objProgress);
1892	}
1893	
1894	
1895	/**
1896	 * add to button ug-nohover class on ipad
1897	 * need to be processed in css
1898	 */
1899	this.setButtonMobileReady = function(objButton){
1900		
1901		objButton.on("touchstart",function(event){
1902			//event.preventDefault();
1903			jQuery(this).addClass("ug-nohover");
1904		});
1905		
1906		objButton.on("mousedown touchend",function(event){
1907			
1908			//debugLine("button touchend",true,true);
1909			//event.preventDefault();
1910			event.stopPropagation();
1911			event.stopImmediatePropagation();
1912			
1913			//debugLine(event.type, true, true);
1914			
1915			return(false);
1916		});
1917		
1918	}
1919	
1920	
1921	/**
1922	 * register gallery theme
1923	 */
1924	this.registerTheme = function(themeName){
1925		
1926		g_temp.arrThemes.push(themeName);
1927	}
1928	
1929	/**
1930	 * get themes array
1931	 */
1932	this.getArrThemes = function(){
1933		
1934		return(g_temp.arrThemes);
1935	}
1936	
1937	
1938	/**
1939	 * check if theme exists
1940	 */
1941	this.isThemeRegistered = function(theme){
1942	
1943		if(jQuery.inArray(theme, g_temp.arrThemes) !== -1)
1944			return(true);
1945		
1946		return(false);
1947	}
1948	
1949	/**
1950	 * get first registered theme name
1951	 */
1952	this.getFirstRegisteredTheme = function(){
1953		if(g_temp.arrThemes.length == 0)
1954			return("");
1955		var themeName = g_temp.arrThemes[0];
1956		
1957		return(themeName);
1958	}
1959
1960	
1961	
1962	
1963	/**
1964	 * function checks if enought time passsed between function calls.
1965	 * good for filtering same time events
1966	 */
1967	this.isTimePassed = function(handlerName, timeLimit){
1968		
1969		if(!timeLimit)
1970			var timeLimit = 100;
1971		
1972		var currentTime = jQuery.now();
1973		if(g_temp.timeCache.hasOwnProperty(handlerName) == false)
1974			lastTime = 0;
1975		else
1976			lastTime = g_temp.timeCache[handlerName];
1977		
1978		var diffTime = currentTime - lastTime;
1979		
1980		g_temp.timeCache[handlerName] = currentTime;
1981		
1982		//debugLine(diffTime,true,true);
1983		
1984		if(diffTime <= timeLimit)
1985			return(false);
1986				
1987		return(true);
1988	}
1989	
1990	
1991	/**
1992	 * check if continious event is over like resize
1993	 */
1994	this.whenContiniousEventOver = function(handlerName, onEventOver, timeLimit){
1995		
1996		if(!timeLimit)
1997			var timeLimit = 300;
1998		
1999		
2000		if(g_temp.timeCache.hasOwnProperty(handlerName) == true && g_temp.timeCache[handlerName] != null){
2001			clearTimeout(g_temp.timeCache[handlerName]);
2002			g_temp.timeCache[handlerName] = null;			
2003		}
2004		
2005		g_temp.timeCache[handlerName] = setTimeout(onEventOver, timeLimit);
2006	}
2007	
2008	
2009	/**
2010	 * validate click and touchstart events. 
2011	 * if click comes after touchstart, return false.
2012	 */
2013	this.validateClickTouchstartEvent = function(eventType){
2014		
2015		var returnVal = true;
2016		
2017		var diff = jQuery.now() - g_temp.lastEventTime;
2018		
2019		//debugLine({lastType:g_temp.lastEventType, diff:diff},true, true);
2020		
2021		if(eventType == "click" && g_temp.lastEventType == "touchstart" && diff < 1000)
2022			returnVal = false;
2023		
2024		g_temp.lastEventTime = jQuery.now();
2025		g_temp.lastEventType = eventType;
2026		
2027		return(returnVal);
2028	}
2029	
2030	/**
2031	 * add some class on hover (hover event)
2032	 */
2033	this.addClassOnHover = function(element,className){
2034		if(!className)
2035			var className = "ug-button-hover";
2036		
2037		element.hover(function(){
2038			jQuery(this).addClass(className);
2039		},function(){				
2040			jQuery(this).removeClass(className);
2041		});
2042		
2043	}
2044	
2045	/**
2046	 * destroy hover effect on elements
2047	 */
2048	this.destroyButton = function(element){
2049		element.off("mouseenter");
2050		element.off("mouseleave");
2051		element.off("click");
2052		element.off("touchstart");
2053		element.off("touchend");
2054		element.off("mousedown");
2055	}
2056	
2057	/**
2058	 * set button on click event, advanced
2059	 */
2060	this.setButtonOnClick = function(objButton, onClickFunction){
2061		
2062		t.setButtonMobileReady(objButton);
2063		
2064		objButton.on("click touchstart", function(event){
2065			
2066			objThis = jQuery(this);
2067						
2068			event.stopPropagation();
2069			event.stopImmediatePropagation();
2070			
2071			if(t.validateClickTouchstartEvent(event.type) == false)
2072				return(true);
2073			
2074			onClickFunction(objThis, event);
2075		});
2076		
2077	}
2078	
2079	/**
2080	 * load javascript dynamically
2081	 */
2082	this.loadJs = function(url, addProtocol){
2083		
2084		if(addProtocol === true)
2085			url = location.protocol + "//" + url;
2086		
2087		var tag = document.createElement('script');
2088		tag.src = url;
2089		var firstScriptTag = document.getElementsByTagName('script')[0];
2090		firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);		
2091	}
2092	
2093	/**
2094	 * load css dymanically
2095	 */
2096	this.loadCss = function(url, addProtocol){
2097		if(addProtocol === true)
2098			url = location.protocol + "//" + url;
2099		
2100		var tag=document.createElement("link");
2101		  tag.setAttribute("rel", "stylesheet");
2102		  tag.setAttribute("type", "text/css");
2103		  tag.setAttribute("href", url);
2104		  
2105		document.getElementsByTagName("head")[0].appendChild(tag);
2106	}
2107	
2108	/**
2109	 * add event listener with old browsers fallback
2110	 */
2111	 this.addEvent = function(elem, event, func ) {
2112		 
2113		 if (typeof (elem.addEventListener) != "undefined") {
2114			 elem.addEventListener(event, func, false);
2115		    } else if (elem.attachEvent) {
2116		    	elem.attachEvent('on' + event, func);
2117		  }
2118		 
2119	  }
2120
2121
2122
2123
2124	/**
2125	 * fire event where all images are loaded
2126	 */
2127	this.checkImagesLoaded = function(objImages, onComplete, onProgress){
2128		
2129		var arrImages = [];
2130		var counter = 0;
2131		var numImages = objImages.length;
2132		
2133		//if no images - exit
2134		if(numImages == 0 && onComplete){
2135			onComplete();
2136			return(false);
2137		}
2138		
2139		//nested function
2140		function checkComplete(image, isError){
2141			counter++;
2142						
2143			if(typeof onProgress == "function"){
2144				
2145				setTimeout(function(){
2146					onProgress(image, isError);
2147				});
2148			}
2149			
2150			if(counter == numImages && typeof onComplete == "function"){
2151				setTimeout(function(){
2152					onComplete();
2153				});
2154			}
2155			
2156		}
2157
2158
2159		//start a little later
2160		setTimeout(function(){
2161			
2162			//start the function
2163			for(var index=0;index < numImages; index++){
2164				var image = objImages[index];
2165				
2166				//arrImages.push(jQuery(image));
2167				if(image.naturalWidth !== undefined && image.naturalWidth !== 0){
2168					checkComplete(objImages[index], false);
2169				}
2170				else{
2171					var proxyImage = jQuery('<img/>');
2172					proxyImage.data("index", index);
2173					
2174					proxyImage.on("load", function(){
2175						var index = jQuery(this).data("index");
2176						checkComplete(objImages[index], false);
2177					});
2178					proxyImage.on("error", function(){
2179						var index = jQuery(this).data("index");
2180						checkComplete(objImages[index], true);
2181					});
2182					proxyImage.attr("src", image.src);			
2183				}
2184			}
2185			
2186		});
2187		
2188		
2189	}
2190	
2191	
2192	/**
2193	 * run the function when the element size will be not 0
2194	 */
2195	this.waitForWidth = function(element, func){
2196		var width = element.width();
2197		if(width != 0){
2198			func();
2199			return(false);
2200		}
2201
2202		g_temp.handle = setInterval(function(){
2203			width = element.width();
2204			if(width != 0){
2205				clearInterval(g_temp.handle);
2206				func();				
2207			}
2208
2209		}, 300);
2210		
2211	}
2212	
2213	/**
2214	 * shuffle (randomise) array
2215	 */
2216	this.arrayShuffle = function(arr){
2217		
2218		if(typeof arr != "object")
2219			return(arr);
2220			
2221	    for(var j, x, i = arr.length; i; j = parseInt(Math.random() * i), x = arr[--i], arr[i] = arr[j], arr[j] = x);
2222	    return arr;
2223	}
2224
2225	
2226	/**
2227	 * get object length
2228	 */
2229	this.getObjectLength = function(object){
2230		var num = 0;
2231		for(var item in object)
2232			num++;
2233		return num;
2234	}
2235
2236	/**
2237	 * normalize the percent, return always between 0 and 1
2238	 */
2239	this.normalizePercent = function(percent){
2240		
2241		if(percent < 0)
2242			percent = 0;
2243		
2244		if(percent > 1)
2245			percent = 1;
2246		
2247		return(percent);
2248	}
2249	
2250	
2251	/**
2252	 * strip tags from string
2253	 */
2254	this.stripTags = function (html) {
2255        // 20240207 ajout de la vérification d'undefined car certaines images n'avaient pas de title
2256	    if (html == null) return ("");
2257		var text = html.replace(/(<([^>]+)>)/ig,"");
2258		
2259		return(text);
2260	}
2261	
2262	
2263	/**
2264	 * escape double slash
2265	 */
2266	this.escapeDoubleSlash = function(str){
2267		
2268		return str.replace('"','\"');
2269	}
2270	
2271	
2272	/**
2273	 * html entitles
2274	 */
2275	this.htmlentitles = function(html){
2276		var text = jQuery('<div/>').text(html).html();
2277		return(text);
2278	}
2279	
2280	
2281	this.z_________END_GENERAL_FUNCTIONS_______ = function(){}
2282	
2283}
2284
2285
2286
2287var g_ugFunctions = new UGFunctions();
2288
2289
2290/** -------------- END UgFunctions class ---------------------*/
2291
2292
2293
2294/** -------------- MouseWheel ---------------------*/
2295
2296!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)}})});
2297
2298/** -------------- EASING FUNCTIONS ---------------------*/
2299
2300(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}})});
2301
2302/** -------------- JQuery Color Animations ---------------------*/
2303
2304!function(r,n){
2305	if(typeof r.cssHooks == "undefined")		//error protection
2306		return(false);
2307	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 2307
2307!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,
2307null,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);
2308
2309
2310/** -------------- SOME GENERAL FUNCTIONS ---------------------*/
2311
2312/**
2313 * ismouseover function - check if the mouse over some object
2314 */
2315!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);
2316
2317
2318
2319function UGThumbsGeneral(){
2320	
2321	var t = this, g_objThis = jQuery(t);
2322	
2323	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objects, g_objWrapper; 
2324	var g_arrItems, g_objStrip, g_objParent;
2325	var g_functions = new UGFunctions();
2326	var g_strip;
2327	var outer_options;
2328
2329	this.events = {		
2330		SETOVERSTYLE: "thumbmouseover",
2331		SETNORMALSTYLE: "thumbmouseout",
2332		SETSELECTEDSTYLE: "thumbsetselected",
2333		
2334		PLACEIMAGE: "thumbplaceimage",
2335		AFTERPLACEIMAGE: "thumb_after_place_image",
2336		IMAGELOADERROR: "thumbimageloaderror",
2337		THUMB_IMAGE_LOADED: "thumb_image_loaded"
2338	};
2339	
2340	var g_options = {
2341			thumb_width:88,								//thumb width
2342			thumb_height:50,							//thumb height
2343			thumb_fixed_size: true,						//true,false - fixed/dynamic thumbnail width
2344			thumb_resize_by: "height",					//set resize by width or height of the image in case of non fixed size, 
2345			
2346			thumb_border_effect:true,					//true, false - specify if the thumb has border
2347			thumb_border_width: 0,						//thumb border width
2348			thumb_border_color: "#000000",				//thumb border color
2349			thumb_over_border_width: 0,					//thumb border width in mouseover state
2350			thumb_over_border_color: "#d9d9d9",			//thumb border color in mouseover state
2351			thumb_selected_border_width: 1,				//thumb width in selected state
2352			thumb_selected_border_color: "#d9d9d9",		//thumb border color in selected state
2353			
2354			thumb_round_corners_radius:0,				//thumb border radius
2355			
2356			thumb_color_overlay_effect: true,			//true,false - thumb color overlay effect, release the overlay on mouseover and selected states
2357			thumb_overlay_color: "#000000",				//thumb overlay color
2358			thumb_overlay_opacity: 0.4,					//thumb overlay color opacity
2359			thumb_overlay_reverse:false,				//true,false - reverse the overlay, will be shown on selected state only
2360			
2361			thumb_image_overlay_effect: false,			//true,false - images orverlay effect on normal state only
2362			thumb_image_overlay_type: "bw",				//bw , blur, sepia - the type of image effect overlay, black and white, sepia and blur.
2363			
2364			thumb_transition_duration: 200,				//thumb effect transition duration
2365			thumb_transition_easing: "easeOutQuad",		//thumb effect transition easing
2366			
2367			thumb_show_loader: true,					//show thumb loader while loading the thumb
2368			thumb_loader_type: "dark",					//dark, light - thumb loader type
2369			
2370			thumb_wrapper_as_link: false,				//set thumb as link
2371			thumb_link_newpage: false					//set the link to open newpage
2372		}
2373	
2374		var g_temp = {
2375			touchEnabled: false,
2376			num_thumbs_checking:0,
2377			customThumbs:false,
2378			funcSetCustomThumbHtml:null,
2379			isEffectBorder: false,
2380			isEffectOverlay: false,
2381			isEffectImage: false,
2382			colorOverlayOpacity: 1,
2383			thumbInnerReduce: 0,
2384			allowOnResize: true		//allow onresize event
2385		};
2386		
2387	
2388		var g_serviceParams = {			//service variables	
2389			timeout_thumb_check:100,
2390			thumb_max_check_times:600,	//60 seconds
2391			eventSizeChange: "thumb_size_change"
2392		};
2393
2394		/**
2395		 * init the thumbs object
2396		 */
2397		this.init = function(gallery, customOptions){
2398			g_objects = gallery.getObjects();
2399			g_gallery = gallery;
2400			g_objGallery = jQuery(gallery);
2401			g_objWrapper = g_objects.g_objWrapper;
2402			g_arrItems = g_objects.g_arrItems;
2403
2404			g_options = jQuery.extend(g_options, customOptions);
2405
2406			//set effects vars:
2407			g_temp.isEffectBorder = g_options.thumb_border_effect;
2408			g_temp.isEffectOverlay = g_options.thumb_color_overlay_effect;
2409			g_temp.isEffectImage = g_options.thumb_image_overlay_effect;
2410		
2411		}
2412		
2413		this._____________EXTERNAL_SETTERS__________ = function(){};
2414		
2415		/**
2416		 * append the thumbs html to some parent
2417		 */
2418		this.setHtmlThumbs = function(objParent){
2419					
2420			g_objParent = objParent;
2421			
2422			var numItems = g_gallery.getNumItems();
2423
2424			//set image effect class
2425			if(g_temp.isEffectImage == true){
2426				var imageEffectClass = getImageEffectsClass();
2427			}
2428			
2429			 //append thumbs to strip
2430			 for(var i=0;i<numItems;i++){
2431				 
2432				 var objItem = g_arrItems[i];
2433				 
2434				 var classAddition = "";
2435				 if(g_temp.customThumbs == false)
2436					 classAddition = " ug-thumb-generated";
2437				
2438				var zIndex = objItem.index + 1;
2439				var thumbStyle = "style='z-index:"+zIndex+";'";
2440				
2441			 	var htmlThumb = "<div class='ug-thumb-wrapper"+classAddition+"' " + thumbStyle + "></div>";
2442
2443				 if(g_options.thumb_wrapper_as_link == true){
2444					 var urlLink = objItem.link;
2445					 if(objItem.link == "")
2446						 urlLink = "javascript:void(0)";
2447					
2448					 var linkTarget = "";
2449						if(g_options.thumb_link_newpage == true && objItem.link)
2450							linkTarget = " target='_blank'";
2451					 
2452					 var htmlThumb = "<a href='" + urlLink + "'"+linkTarget+" class='ug-thumb-wrapper"+classAddition+"'></a>";
2453				 }
2454				 
2455				 var objThumbWrapper = jQuery(htmlThumb);
2456				 
2457				 var objImage = objItem.objThumbImage;
2458				
2459				 if(g_temp.customThumbs == false){
2460 				 
2461					 if(g_options.thumb_show_loader == true && objImage){
2462						 
2463						 var loaderClass = "ug-thumb-loader-dark";
2464						 if(g_options.thumb_loader_type == "bright")
2465							 loaderClass = "ug-thumb-loader-bright";
2466						 
2467						 objThumbWrapper.append("<div class='ug-thumb-loader " + loaderClass + "'></div>");
2468						 objThumbWrapper.append("<div class='ug-thumb-error' style='display:none'></div>");
2469					 }
2470					 					 
2471					 if(objImage){
2472						 objImage.addClass("ug-thumb-image");
2473						 
2474						 //if image overlay effects active, clone the image, and set the effects class on it
2475						 if(g_options.thumb_image_overlay_effect == true){
2476							var objImageOverlay = objImage.clone().appendTo(objThumbWrapper);
2477							
2478							objImageOverlay.addClass("ug-thumb-image-overlay " + imageEffectClass).removeClass("ug-thumb-image");
2479							objImageOverlay.fadeTo(0,0);
2480							objItem.objImageOverlay = objImageOverlay;
2481						 }
2482								 
2483						 objThumbWrapper.append(objImage);
2484					 }
2485					 
2486				 }//end if not custom thumb
2487				 
2488				 if(g_temp.isEffectBorder)
2489					 objThumbWrapper.append("<div class='ug-thumb-border-overlay'></div>");
2490				 
2491				 if(g_temp.isEffectOverlay)
2492					 objThumbWrapper.append("<div class='ug-thumb-overlay'></div>");
2493				 
2494				 g_objParent.append(objThumbWrapper);
2495
2496				 //only custom thumbs function
2497				 if(g_temp.customThumbs){
2498					 
2499					 g_temp.funcSetCustomThumbHtml(objThumbWrapper, objItem);
2500					 
2501				 }
2502				 
2503				 //add thumb wrapper object to items array
2504				 g_arrItems[i].objThumbWrapper = objThumbWrapper;
2505				 
2506			 }
2507		}
2508
2509		
2510		function _______________SETTERS______________(){};
2511
2512		
2513		/**
2514		 * set thumb size with all the inside components (without the image).
2515		 * else, set to all the thumbs
2516		 */
2517		function setThumbSize(width, height, objThumb, innerOnly){
2518						
2519			var objCss = {
2520				width: width+"px",
2521				height: height+"px"
2522			};
2523			
2524			var objCssInner = {
2525					width: width-g_temp.thumbInnerReduce+"px",
2526					height: height-g_temp.thumbInnerReduce+"px"
2527				};
2528			
2529			var selectorsString = ".ug-thumb-loader, .ug-thumb-error, .ug-thumb-border-overlay, .ug-thumb-overlay";
2530			
2531			//set thumb size
2532			if(objThumb){
2533				if(innerOnly !== true)
2534					objThumb.css(objCss);
2535				
2536				objThumb.children(selectorsString).css(objCssInner);
2537			}
2538			else{	//set to all items
2539				g_objParent.children(".ug-thumb-wrapper").css(objCss);
2540				g_objParent.find(selectorsString).css(objCssInner);
2541			}
2542			
2543		}
2544
2545		
2546		/**
2547		 * set thumb border effect
2548		 */
2549		function setThumbBorderEffect(objThumb, borderWidth, borderColor, noAnimation){
2550						
2551			if(!noAnimation)
2552				var noAnimation = false;
2553			
2554			if(g_gallery.isFakeFullscreen())
2555				noAnimation = true;
2556			
2557			var objBorderOverlay = objThumb.children(".ug-thumb-border-overlay");
2558			
2559			//set the border to thumb and not to overlay if no border size transition
2560			/*
2561			if(g_options.thumb_border_width == g_options.thumb_over_border_width
2562				&& g_options.thumb_border_width == g_options.thumb_selected_border_width)
2563				objBorderOverlay = objThumb;
2564			*/
2565			
2566			var objCss = {};
2567			
2568			objCss["border-width"] = borderWidth + "px";
2569			
2570			if(borderWidth != 0)
2571				objCss["border-color"] = borderColor;
2572			
2573			if(noAnimation && noAnimation === true){
2574				objBorderOverlay.css(objCss);
2575				
2576				if(borderWidth == 0)
2577					objBorderOverlay.hide();
2578				else
2579					objBorderOverlay.show();
2580			}
2581			else{
2582				
2583				if(borderWidth == 0)
2584					objBorderOverlay.stop().fadeOut(g_options.thumb_transition_duration);
2585				else
2586					objBorderOverlay.show().stop().fadeIn(g_options.thumb_transition_duration);
2587				
2588				animateThumb(objBorderOverlay, objCss);
2589			}
2590		
2591		}
2592		
2593		
2594		/**
2595		 * set thumb border effect
2596		 */
2597		function setThumbColorOverlayEffect(objThumb, isActive, noAnimation){
2598			
2599			var objOverlay = objThumb.children(".ug-thumb-overlay");
2600			
2601			var animationDuration = g_options.thumb_transition_duration;
2602			if(noAnimation && noAnimation === true)
2603				animationDuration = 0;
2604			
2605			if(isActive){
2606				objOverlay.stop(true).fadeTo(animationDuration, g_temp.colorOverlayOpacity);
2607			}else{
2608				objOverlay.stop(true).fadeTo(animationDuration, 0);
2609			}
2610			
2611		}
2612		
2613		
2614		/**
2615		 * set thumbnail bw effect
2616		 */
2617		function setThumbImageOverlayEffect(objThumb, isActive, noAnimation){
2618			
2619			var objImage = objThumb.children("img.ug-thumb-image");
2620			var objImageOverlay = objThumb.children("img.ug-thumb-image-overlay");
2621					
2622			var animationDuration = g_options.thumb_transition_duration;
2623			if(noAnimation && noAnimation === true)
2624				animationDuration = 0;
2625						
2626			if(isActive){
2627				objImageOverlay.stop(true).fadeTo(animationDuration,1);
2628			}else{
2629				//show the image, hide the overlay
2630				objImage.fadeTo(0,1);
2631				objImageOverlay.stop(true).fadeTo(animationDuration,0);
2632			}
2633			
2634		}
2635		
2636		
2637		/**
2638		 * on thumb mouse out - return the thumb style to original
2639		 */
2640		this.setThumbNormalStyle = function(objThumb, noAnimation, fromWhere){
2641			
2642			if(g_temp.customThumbs == true){
2643				objThumb.removeClass("ug-thumb-over");
2644			}
2645			
2646			if(g_temp.isEffectBorder)
2647			  setThumbBorderEffect(objThumb, g_options.thumb_border_width, g_options.thumb_border_color, noAnimation);
2648			
2649			if(g_temp.isEffectOverlay){
2650				var isSet = (g_options.thumb_overlay_reverse == true)?false:true;
2651				setThumbColorOverlayEffect(objThumb, isSet, noAnimation);
2652			}
2653						
2654			if(g_temp.isEffectImage){
2655				setThumbImageOverlayEffect(objThumb, true, noAnimation);
2656			}
2657			
2658			g_objThis.trigger(t.events.SETNORMALSTYLE, objThumb);
2659		}
2660		
2661		
2662		/**
2663		 * on thumb mouse over - turn thumb style to over position
2664		 */
2665		this.setThumbOverStyle = function(objThumb){
2666			
2667			if(g_temp.customThumbs == true){
2668				objThumb.addClass("ug-thumb-over");
2669			}
2670			
2671			//border effect
2672			if(g_temp.isEffectBorder)
2673				setThumbBorderEffect(objThumb, g_options.thumb_over_border_width, g_options.thumb_over_border_color);
2674			
2675			//color overlay effect 
2676			if(g_temp.isEffectOverlay){
2677				var isSet = (g_options.thumb_overlay_reverse == true)?true:false;
2678				setThumbColorOverlayEffect(objThumb, isSet);
2679			}
2680			
2681			//image overlay effect
2682			if(g_temp.isEffectImage == true){
2683				setThumbImageOverlayEffect(objThumb, false);
2684			}
2685			
2686			//trigger event for parent classes
2687			g_objThis.trigger(t.events.SETOVERSTYLE, objThumb);
2688		}
2689		
2690		
2691		/**
2692		 * set thumb selected style
2693		 */
2694		function setThumbSelectedStyle(objThumb, noAnimation){
2695						
2696			if(g_temp.isEffectBorder)			
2697				setThumbBorderEffect(objThumb, g_options.thumb_selected_border_width, g_options.thumb_selected_border_color, noAnimation);
2698			
2699			if(g_temp.isEffectOverlay){
2700				var isSet = (g_options.thumb_overlay_reverse == true)?true:false;
2701				setThumbColorOverlayEffect(objThumb, isSet, noAnimation);
2702			}
2703			
2704			//image overlay effect
2705			if(g_temp.isEffectImage)
2706				setThumbImageOverlayEffect(objThumb, false, noAnimation);
2707
2708			
2709			g_objThis.trigger(t.events.SETSELECTEDSTYLE, objThumb);
2710
2711		}
2712		
2713		
2714		/**
2715		 * set loading error of the thumb
2716		 */
2717		function setItemThumbLoadedError(objThumb){
2718			
2719			var objItem = t.getItemByThumb(objThumb);
2720			
2721			objItem.isLoaded = true;
2722			objItem.isThumbImageLoaded = false;		
2723			
2724			if(g_temp.customThumbs == true){
2725				
2726				g_objThis.trigger(t.events.IMAGELOADERROR, objThumb);
2727				return(true);
2728			
2729			}
2730			
2731			objThumb.children(".ug-thumb-loader").hide();
2732			objThumb.children(".ug-thumb-error").show();		
2733		}
2734		
2735		
2736		/**
2737		 * set border radius of all the thmbs
2738		 */
2739		function setThumbsBorderRadius(){
2740						
2741			if(g_options.thumb_round_corners_radius <= 0)
2742				return(false);
2743			
2744			//set radius:
2745			var objCss = {
2746				"border-radius":g_options.thumb_round_corners_radius + "px"
2747			};
2748			
2749			g_objParent.find(".ug-thumb-wrapper, .ug-thumb-wrapper .ug-thumb-border-overlay").css(objCss);
2750			
2751		}
2752		
2753		
2754		/**
2755		 * animate thumb transitions
2756		 */
2757		function animateThumb(objThumb, objThumbCss){
2758			
2759			objThumb.stop(true).animate(objThumbCss ,{
2760				duration: g_options.thumb_transition_duration,
2761				easing: g_options.thumb_transition_easing,
2762				queue: false
2763			});
2764					
2765		}
2766		
2767		
2768		/**
2769		 * redraw the thumb style according the state
2770		 */
2771		function redrawThumbStyle(objThumb){
2772
2773			if(isThumbSelected(objThumb) == true)
2774				setThumbSelectedStyle(objThumb, true, "redraw");
2775			else
2776				t.setThumbNormalStyle(objThumb, true, "redraw");
2777		}
2778		
2779		
2780		
2781		
2782		/**
2783		 * place thumb image
2784		 * retrun - false, if already loaded
2785		 * return true - if was set on this function
2786		 * isForce - set the image anyway
2787		 */
2788		function placeThumbImage(objThumb, objImage, objItem){
2789			
2790			//scale the image
2791			if(g_options.thumb_fixed_size == true){
2792				g_functions.scaleImageCoverParent(objImage, objThumb);
2793			}
2794			else{
2795				
2796				//variant size
2797				
2798				if(g_options.thumb_resize_by == "height")	//horizontal strip
2799					g_functions.scaleImageByHeight(objImage, g_options.thumb_height);
2800				else		//vertical strip
2801					g_functions.scaleImageByWidth(objImage, g_options.thumb_width);
2802				
2803				var imageSize = g_functions.getElementSize(objImage);
2804				g_functions.placeElement(objImage, 0, 0);
2805				setThumbSize(imageSize.width, imageSize.height, objThumb);
2806				
2807			}
2808			
2809			//hide loader
2810			objThumb.children(".ug-thumb-loader").hide();
2811			
2812			//show image
2813			objImage.show();
2814			
2815			//if overlay effect exists
2816			if(g_options.thumb_image_overlay_effect == false){
2817				objImage.fadeTo(0,1);
2818			}
2819			else{
2820
2821				//place bw image also if exists
2822				if(g_options.thumb_image_overlay_effect == true){
2823					copyPositionToThumbOverlayImage(objImage);
2824				}
2825
2826				//hide the original image (avoid blinking at start)
2827				objImage.fadeTo(0,0);
2828
2829				//redraw the style, because this function can overwrite it
2830				redrawThumbStyle(objThumb);
2831			}
2832			
2833			g_objThis.trigger(t.events.AFTERPLACEIMAGE, objThumb);
2834			
2835		}
2836
2837
2838		
2839		/**
2840		 * copy image position to bw image (if exists)
2841		 */
2842		function copyPositionToThumbOverlayImage(objImage){
2843						
2844			var objImageBW = objImage.siblings(".ug-thumb-image-overlay");
2845			if(objImageBW.length == 0)
2846				return(false);
2847			
2848			var objSize = g_functions.getElementSize(objImage);
2849				
2850			var objCss = {
2851					"width":objSize.width+"px",
2852					"height":objSize.height+"px",
2853					"left":objSize.left+"px",
2854					"top":objSize.top+"px"
2855				}
2856				
2857			objImageBW.css(objCss);
2858			
2859			//show the image
2860			if(g_temp.customThumbs == false)
2861				objImageBW.fadeTo(0,1);
2862			
2863		}
2864		
2865		
2866		
2867		
2868		function _______________GETTERS______________(){};
2869		
2870		
2871		/**
2872		 * get the image effects class from the options
2873		 */
2874		function getImageEffectsClass(){
2875			
2876			var imageEffectClass = "";
2877			var arrEffects = g_options.thumb_image_overlay_type.split(",");
2878			
2879			for(var index in arrEffects){
2880				var effect = arrEffects[index];
2881				
2882				switch(effect){
2883					case "bw":
2884						imageEffectClass += " ug-bw-effect";
2885					break;
2886					case "blur":
2887						imageEffectClass += " ug-blur-effect";
2888					break; 
2889					case "sepia":
2890						imageEffectClass += " ug-sepia-effect";
2891					break;
2892				}
2893			}
2894					
2895			return(imageEffectClass);
2896		}
2897
2898		/**
2899		 * get if the thumb is selected
2900		 */
2901		function isThumbSelected(objThumbWrapper){
2902			
2903			if(objThumbWrapper.hasClass("ug-thumb-selected"))
2904				return(true);
2905			
2906			return(false);
2907		}
2908
2909		
2910		function _______________EVENTS______________(){};
2911		
2912		/**
2913		 * on thumb size change - triggered by parent on custom thumbs type
2914		 */
2915		function onThumbSizeChange(temp, objThumb){
2916			
2917			objThumb = jQuery(objThumb);
2918			var objItem = t.getItemByThumb(objThumb);
2919			
2920			var objSize = g_functions.getElementSize(objThumb);
2921			
2922			setThumbSize(objSize.width, objSize.height, objThumb, true);
2923			
2924			redrawThumbStyle(objThumb);
2925		}
2926		
2927		
2928		/**
2929		 * on thumb mouse over
2930		 */
2931		function onMouseOver(objThumb){
2932			
2933			
2934			//if touch enabled unbind event
2935			if(g_temp.touchEnabled == true){
2936				objThumbs.off("mouseenter").off("mouseleave");
2937				return(true);
2938			}
2939			
2940			if(isThumbSelected(objThumb) == false)
2941				t.setThumbOverStyle(objThumb);
2942			
2943		}
2944		
2945		
2946		/**
2947		 * on thumb mouse out
2948		 */
2949		function onMouseOut(objThumb){
2950			
2951			if(g_temp.touchEnabled == true)
2952				return(true);
2953							
2954			if(isThumbSelected(objThumb) == false)
2955				t.setThumbNormalStyle(objThumb, false);
2956		}
2957		
2958		
2959		/**
2960		 * on image loaded event
2961		 */
2962		function onImageLoaded(image, isForce){
2963
2964			if(!isForce)
2965				var isForce = false;
2966			
2967			var objImage = jQuery(image);
2968			var objThumb = objImage.parents(".ug-thumb-wrapper");
2969			
2970			if(objThumb.parent().length == 0)		//don't treat detached thumbs
2971				return(false);
2972						
2973			objItem = t.getItemByThumb(objThumb);
2974			
2975			if(objItem.isLoaded == true && isForce === false)
2976				return(false);
2977			
2978			t.triggerImageLoadedEvent(objThumb, objImage);
2979			
2980			if(g_temp.customThumbs == true){
2981				
2982				g_objThis.trigger(t.events.PLACEIMAGE, [objThumb, objImage]);
2983			
2984			}else{
2985				
2986				placeThumbImage(objThumb, objImage, objItem);
2987				
2988			}
2989			
2990		}
2991		
2992		
2993		/**
2994		 * on image loaded - set appropriete item vars
2995		 */
2996		function onThumbImageLoaded(data, objThumb, objImage){
2997			
2998			objItem = t.getItemByThumb(objThumb);
2999						
3000			objItem.isLoaded = true;
3001			objItem.isThumbImageLoaded = true;
3002			
3003			var objSize = g_functions.getImageOriginalSize(objImage);
3004			
3005			objItem.thumbWidth = objSize.width;
3006			objItem.thumbHeight = objSize.height;
3007			objItem.thumbRatioByWidth = objSize.width / objSize.height;
3008			objItem.thumbRatioByHeight = objSize.height / objSize.width;
3009			
3010		}
3011
3012		
3013		/**
3014		 * set thumbnails html properties
3015		 */
3016		this.setHtmlProperties = function(){
3017						
3018			 //set thumb params
3019			if(g_temp.customThumbs == false){
3020				var objThumbCss = {};
3021			
3022				//set thumb fixed size
3023				if(g_options.thumb_fixed_size == true)
3024					setThumbSize(g_options.thumb_width, g_options.thumb_height);
3025					
3026				 setThumbsBorderRadius();
3027			}
3028			 
3029			 //set normal style to all the thumbs
3030			 g_objParent.children(".ug-thumb-wrapper").each(function(){
3031				 var objThumb = jQuery(this);
3032				 redrawThumbStyle(objThumb);
3033			 });
3034			
3035
3036			//set color. if empty set from css
3037			if(g_temp.isEffectOverlay){
3038				
3039				if(g_options.thumb_overlay_color){
3040										
3041					var objCss = {};
3042					if(g_functions.isRgbaSupported()){
3043						var colorRGB = g_functions.convertHexToRGB(g_options.thumb_overlay_color, g_options.thumb_overlay_opacity);
3044						objCss["background-color"] = colorRGB;										
3045					}else{
3046						objCss["background-color"] = g_options.thumb_overlay_color;
3047						g_temp.colorOverlayOpacity = g_options.thumb_overlay_opacity;
3048					}
3049					
3050					g_objParent.find(".ug-thumb-wrapper .ug-thumb-overlay").css(objCss);
3051				}
3052				
3053			}
3054			
3055		}
3056
3057				
3058		/**
3059		 * set the thumb on selected state
3060		 */
3061		this.setThumbSelected = function(objThumbWrapper){
3062			
3063			if(g_temp.customThumbs == true)
3064				objThumbWrapper.removeClass("ug-thumb-over");
3065			
3066			if(isThumbSelected(objThumbWrapper) == true)
3067				return(true);
3068			
3069			objThumbWrapper.addClass("ug-thumb-selected");
3070			
3071			//set thumb selected style
3072			setThumbSelectedStyle(objThumbWrapper);
3073		}
3074		
3075		/**
3076		 * set the thumb unselected state
3077		 */
3078		this.setThumbUnselected = function(objThumbWrapper){
3079			
3080			//remove the selected class
3081			objThumbWrapper.removeClass("ug-thumb-selected");
3082			
3083			t.setThumbNormalStyle(objThumbWrapper, false, "set unselected");
3084		}
3085		
3086		
3087		/**
3088		 * set the options of the strip
3089		 */
3090		this.setOptions = function(objOptions){
3091			
3092			g_options = jQuery.extend(g_options, objOptions);
3093			
3094		}
3095		
3096		
3097		/**
3098		 * set thumb inner reduce - reduce this number when resizing thumb inner
3099		 */
3100		this.setThumbInnerReduce = function(innerReduce){
3101			
3102			g_temp.thumbInnerReduce = innerReduce;
3103			
3104		}
3105		
3106		/**
3107		 * set custom thumbs
3108		 * allowedEffects - border, overlay, image
3109		 */
3110		this.setCustomThumbs = function(funcSetHtml, arrAlowedEffects, customOptions){
3111			
3112			g_temp.customThumbs = true;
3113						
3114			if(typeof funcSetHtml != "function")
3115				throw new Error("The argument should be function");
3116			
3117			
3118			g_temp.funcSetCustomThumbHtml = funcSetHtml;
3119			
3120			//enable effects:
3121			if(jQuery.inArray("overlay", arrAlowedEffects) == -1)
3122				g_temp.isEffectOverlay = false;				
3123			
3124			if(jQuery.inArray("border", arrAlowedEffects) == -1)
3125				g_temp.isEffectBorder = false;
3126			
3127			g_temp.isEffectImage = false;		//for custom effects the image is always off
3128
3129			//check for dissalow onresize
3130			if(customOptions && customOptions.allow_onresize === false){
3131				g_temp.allowOnResize = false;
3132			}
3133		
3134		}
3135		
3136		
3137		
3138		
3139		
3140		
3141		this._____________EXTERNAL_GETTERS__________ = function(){};
3142
3143		/**
3144		 * get the options object
3145		 */
3146		this.getOptions = function(){
3147			
3148			return(g_options);
3149		}
3150		
3151		
3152		/**
3153		 * get num thumbs
3154		 */
3155		this.getNumThumbs = function(){
3156			var numThumbs = g_arrItems.length;
3157			return(numThumbs);
3158		}
3159
3160		
3161		/**
3162		 * get thumb image
3163		 */
3164		this.getThumbImage = function(objThumb){
3165			
3166			var objImage = objThumb.find(".ug-thumb-image");
3167			return(objImage);
3168		}
3169		
3170		
3171		/**
3172		 * get thumbs by index
3173		 */
3174		this.getThumbByIndex = function(index){
3175			var objThumbs = t.getThumbs();
3176			
3177			if(index >= objThumbs.length || index < 0)
3178				throw new Error("Wrong thumb index");
3179			
3180			var objThumb = jQuery(objThumbs[index]);
3181			
3182			return(objThumb);
3183		}
3184		
3185		
3186		/**
3187		 * get all thumbs jquery object
3188		 */
3189		this.getThumbs = function(){
3190			return(g_objParent.children(".ug-thumb-wrapper"));
3191		}
3192		
3193		/**
3194		 * get item by thumb object
3195		 */
3196		this.getItemByThumb = function(objThumb){
3197			
3198			var index = objThumb.data("index");
3199			
3200			if(index === undefined)
3201				index = objThumb.index();
3202			
3203			var arrItem = g_arrItems[index];
3204			return(arrItem);
3205		}
3206		
3207		
3208		/**
3209		 * is thumb loaded
3210		 */
3211		this.isThumbLoaded = function(objThumb){
3212			
3213			var objItem = t.getItemByThumb(objThumb);
3214			
3215			return(objItem.isLoaded);			
3216		}
3217		
3218		
3219		/**
3220		 * get global thumb size
3221		 */
3222		this.getGlobalThumbSize = function(){
3223			
3224			var objSize = {
3225				width:g_options.thumb_width,
3226				height: g_options.thumb_height
3227			};
3228			
3229			return(objSize);
3230		}
3231		
3232		
3233		this._____________EXTERNAL_OTHERS__________ = function(){};
3234
3235
3236		
3237		/**
3238		 * init events
3239		 */
3240		this.initEvents = function(){
3241			
3242			var objThumbs = g_objParent.find(".ug-thumb-wrapper");
3243			
3244			objThumbs.on("touchstart",function(){
3245				g_temp.touchEnabled = true;
3246				objThumbs.off("mouseenter").off("mouseleave");
3247			});
3248			
3249			if(g_temp.allowOnResize == true)
3250				g_objWrapper.on(g_serviceParams.eventSizeChange, onThumbSizeChange);
3251			
3252			objThumbs.hover(function(event){		//on mouse enter
3253				var objThumb = jQuery(this);
3254				onMouseOver(objThumb);
3255			}, function(event){		//on mouse leave
3256				var objThumb = jQuery(this);
3257				onMouseOut(objThumb);
3258			});
3259			
3260			
3261			//on image loaded event - for setting the image sizes
3262			g_objThis.on(t.events.THUMB_IMAGE_LOADED, onThumbImageLoaded);
3263			
3264		}
3265		
3266		
3267		/**
3268		 * destroy the thumb element
3269		 */
3270		this.destroy = function(){
3271			var objThumbs = g_objParent.find(".ug-thumb-wrapper");
3272			objThumbs.off("touchstart");
3273			g_objWrapper.off(g_serviceParams.eventSizeChange);
3274			objThumbs.off("mouseenter");
3275			objThumbs.off("mouseleave");
3276			g_objThis.off(t.events.THUMB_IMAGE_LOADED);
3277		}
3278		
3279		
3280		/**
3281		 * preload thumbs images and put them into the thumbnails
3282		 */
3283		this.loadThumbsImages = function(){
3284
3285			var objImages = g_objParent.find(".ug-thumb-image");
3286			g_functions.checkImagesLoaded(objImages, null, function(objImage,isError){
3287				
3288				if(isError == false){
3289					onImageLoaded(objImage, true);
3290				}
3291				else{
3292					var objItem = jQuery(objImage).parent();
3293					setItemThumbLoadedError(objItem);										
3294				}
3295			});
3296		}
3297		
3298		
3299		/**
3300		 * trigger image loaded event
3301		 */
3302		this.triggerImageLoadedEvent = function(objThumb, objImage){
3303
3304			g_objThis.trigger(t.events.THUMB_IMAGE_LOADED, [objThumb, objImage]);
3305			
3306		}
3307		
3308		
3309		/**
3310		 * hide thumbs
3311		 */
3312		this.hideThumbs = function(){
3313			
3314			g_objParent.find(".ug-thumb-wrapper").hide();
3315			
3316		}
3317		
3318}
3319
3320/**
3321 * thumbs class
3322 * addon to strip gallery
3323 */
3324function UGThumbsStrip(){
3325
3326	var t = this;
3327	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objects, g_objWrapper; 
3328	var g_arrItems, g_objStrip, g_objStripInner;
3329	var g_aviaControl, g_touchThumbsControl, g_functions = new UGFunctions();	
3330	var g_isVertical = false, g_thumbs = new UGThumbsGeneral();
3331	var g_functions = new UGFunctions();
3332	
3333	var g_options = {
3334		strip_vertical_type: false,
3335		strip_thumbs_align: "left",					//left, center, right, top, middle, bottom - the align of the thumbs when they smaller then the strip size.
3336		strip_space_between_thumbs:6,				//space between thumbs
3337		strip_thumb_touch_sensetivity:15,  			//from 1-100, 1 - most sensetive, 100 - most unsensetive
3338		strip_scroll_to_thumb_duration:500,			//duration of scrolling to thumb
3339		strip_scroll_to_thumb_easing:"easeOutCubic",		//easing of scrolling to thumb animation
3340		strip_control_avia:true,					//avia control - move the strip according str
3340ip moseover position
3341		strip_control_touch:true,					//touch control - move the strip by dragging it
3342		strip_padding_top: 0,						//add some space from the top					
3343		strip_padding_bottom: 0,					//add some space from the bottom
3344		strip_padding_left: 0,						//add some space from left
3345		strip_padding_right: 0						//add some space from right
3346	}
3347	
3348	var g_temp = {
3349		isRunOnce:false,
3350		is_placed:false,
3351		isNotFixedThumbs: false,
3352		handle: null
3353	};
3354	
3355	var g_sizes = {
3356		stripSize:0,		//set after position thumbs
3357		stripActiveSize:0,	//strip size without the padding
3358		stripInnerSize:0,	
3359		thumbSize:0,
3360		thumbSecondSize:0	//size of the height and width of the strip
3361	}
3362	
3363	this.events = {		//events variables
3364			STRIP_MOVE:"stripmove",
3365			INNER_SIZE_CHANGE:"size_change"
3366	}	
3367	
3368	//the defaults for vertical align
3369	var g_defaultsVertical = {
3370		strip_thumbs_align: "top",
3371		thumb_resize_by: "width"
3372	}
3373	
3374	
3375	/**
3376	 * set the thumbs strip html
3377	 */	
3378	this.setHtml = function(objParent){
3379		
3380		if(!objParent){
3381			var objParent = g_objWrapper;
3382			if(g_options.parent_container != null)
3383				objParent = g_options.parent_container;			
3384		}
3385				
3386		objParent.append("<div class='ug-thumbs-strip'><div class='ug-thumbs-strip-inner'></div></div>");		 
3387		g_objStrip = objParent.children(".ug-thumbs-strip");
3388		
3389		g_objStripInner = g_objStrip.children(".ug-thumbs-strip-inner");		
3390				
3391		//put the thumbs to inner strip
3392		g_thumbs.setHtmlThumbs(g_objStripInner);
3393		
3394		//hide thumbs on not fixed mode
3395		if(g_temp.isNotFixedThumbs == true)
3396			g_thumbs.hideThumbs();
3397		
3398	}
3399
3400	
3401	function ___________GENERAL___________(){};
3402	
3403	
3404	/**
3405	 * init the strip
3406	 */
3407	function initStrip(gallery, customOptions){
3408		
3409		g_objects = gallery.getObjects();
3410		g_gallery = gallery;
3411		
3412		g_gallery.attachThumbsPanel("strip", t);
3413		
3414		g_objGallery = jQuery(gallery);
3415		g_objWrapper = g_objects.g_objWrapper;
3416		g_arrItems = g_objects.g_arrItems;
3417
3418		g_options = jQuery.extend(g_options, customOptions);
3419		g_isVertical = g_options.strip_vertical_type;
3420		
3421		//set vertical defaults
3422		if(g_isVertical == true){
3423			g_options = jQuery.extend(g_options, g_defaultsVertical);
3424			g_options = jQuery.extend(g_options, customOptions);
3425			
3426			customOptions.thumb_resize_by = "width";
3427		}
3428		
3429		g_thumbs.init(gallery, customOptions);
3430		
3431		onAfterSetOptions();
3432	}
3433	
3434	
3435	/**
3436	 * run this funcion after set options.
3437	 */
3438	function onAfterSetOptions(){
3439
3440		var thumbsOptions = g_thumbs.getOptions();
3441		
3442		g_temp.isNotFixedThumbs = (thumbsOptions.thumb_fixed_size === false);
3443		g_isVertical = g_options.strip_vertical_type;
3444	}
3445	
3446	
3447	/**
3448	 * run the strip
3449	 */
3450	function runStrip(){
3451		
3452		g_thumbs.setHtmlProperties();
3453		
3454		initSizeParams();
3455
3456		fixSize();
3457
3458		positionThumbs();
3459		
3460		//run only once
3461		if(g_temp.isRunOnce == false){
3462
3463			//init thumbs strip touch
3464			if(g_options.strip_control_touch == true){
3465				g_touchThumbsControl = new UGTouchThumbsControl();
3466				g_touchThumbsControl.init(t);
3467			}
3468
3469			//init thumbs strip avia control
3470			if(g_options.strip_control_avia == true){
3471				g_aviaControl = new UGAviaControl();
3472				g_aviaControl.init(t);
3473			}
3474
3475			checkControlsEnableDisable();
3476
3477			g_thumbs.loadThumbsImages();
3478			
3479			initEvents();
3480		}
3481		
3482						
3483		g_temp.isRunOnce = true;
3484
3485	}
3486	
3487	
3488	/**
3489	 * store strip size and strip active size in vars
3490	 * do after all strip size change
3491	 */
3492	function storeStripSize(size){
3493		
3494		g_sizes.stripSize = size;
3495
3496		if(g_isVertical == false)
3497			g_sizes.stripActiveSize = g_sizes.stripSize - g_options.strip_padding_left - g_options.strip_padding_right;
3498		else
3499			g_sizes.stripActiveSize = g_sizes.stripSize - g_options.strip_padding_top - g_options.strip_padding_bottom;
3500			
3501		if(g_sizes.stripActiveSize < 0)
3502			g_sizes.stripActiveSize = 0;
3503
3504	}
3505	
3506	
3507	/**
3508	 * init some size parameters, before size init and after position thumbs
3509	 */
3510	function initSizeParams(){
3511		
3512		//set thumb outer size:
3513		var arrThumbs = g_objStripInner.children(".ug-thumb-wrapper");
3514		var firstThumb = jQuery(arrThumbs[0]);
3515		var thumbsRealWidth = firstThumb.outerWidth();
3516		var thumbsRealHeight = firstThumb.outerHeight();
3517		var thumbs_options = g_thumbs.getOptions();
3518		
3519		if(g_isVertical == false){			//horizontal
3520			
3521			g_sizes.thumbSize = thumbsRealWidth;
3522		
3523			if(thumbs_options.thumb_fixed_size == true){
3524				g_sizes.thumbSecondSize = thumbsRealHeight;
3525			} else {
3526				g_sizes.thumbSecondSize = thumbs_options.thumb_height;
3527			}
3528			
3529			storeStripSize(g_objStrip.width());
3530			g_sizes.stripInnerSize = g_objStripInner.width();
3531		
3532		}else{		//vertical
3533			g_sizes.thumbSize = thumbsRealHeight;
3534			
3535			if(thumbs_options.thumb_fixed_size == true){
3536				g_sizes.thumbSecondSize = thumbsRealWidth;
3537			} else {
3538				g_sizes.thumbSecondSize = thumbs_options.thumb_width;
3539			}
3540			
3541			storeStripSize(g_objStrip.height());
3542
3543			g_sizes.stripInnerSize = g_objStripInner.height();			
3544		}
3545
3546		
3547	}
3548	
3549	
3550
3551	
3552	/**
3553	 * set size of inner strip according the orientation
3554	 */
3555	function setInnerStripSize(innerSize){
3556
3557		if(g_isVertical == false)
3558			g_objStripInner.width(innerSize);
3559		else
3560			g_objStripInner.height(innerSize);
3561			
3562		g_sizes.stripInnerSize = innerSize;
3563		
3564		checkControlsEnableDisable();
3565		
3566		jQuery(t).trigger(t.events.INNER_SIZE_CHANGE);
3567	}
3568	
3569	
3570	/**
3571	 * position thumbnails in the thumbs panel
3572	 */
3573	function positionThumbs(){
3574		
3575		var arrThumbs = g_objStripInner.children(".ug-thumb-wrapper");
3576		
3577		var posx = 0;
3578		var posy = 0;
3579		
3580		if(g_isVertical == false)
3581			posy = g_options.strip_padding_top;
3582		
3583		for (i = 0; i < arrThumbs.length; i++) {
3584			
3585			var objThumb = jQuery(arrThumbs[i]);
3586			
3587			//skip from placing if not loaded yet on non fixed mode
3588			if(g_temp.isNotFixedThumbs == true){
3589				objItem = g_thumbs.getItemByThumb(objThumb);
3590				if(objItem.isLoaded == false)
3591					continue;
3592				
3593				//the thumb is hidden if not placed
3594				objThumb.show();
3595			}
3596			
3597			g_functions.placeElement(objThumb, posx, posy);
3598			
3599			if(g_isVertical == false)
3600				posx += objThumb.outerWidth() + g_options.strip_space_between_thumbs;
3601			else
3602				posy += objThumb.outerHeight() + g_options.strip_space_between_thumbs;
3603		}
3604		
3605		//set strip size, width or height
3606		if(g_isVertical == false)
3607			var innerStripSize = posx - g_options.strip_space_between_thumbs;
3608		else
3609			var innerStripSize = posy - g_options.strip_space_between_thumbs;
3610			
3611		setInnerStripSize(innerStripSize);
3612	}
3613
3614	
3615	
3616	/**
3617	 * fix strip and inner size
3618	 */
3619	function fixSize(){
3620		
3621		if(g_isVertical == false){		//fix horizontal
3622			
3623			var height = g_sizes.thumbSecondSize;
3624			
3625			 var objCssStrip = {};
3626			 objCssStrip["height"] = height+"px";
3627			 		 
3628			 //set inner strip params
3629			 var objCssInner = {};
3630			 objCssInner["height"] = height+"px";
3631
3632		}else{	//fix vertical
3633			
3634			var width = g_sizes.thumbSecondSize;
3635			
3636			 var objCssStrip = {};
3637			 objCssStrip["width"] = width+"px";
3638			 		 
3639			 //set inner strip params
3640			 var objCssInner = {};
3641			 objCssInner["width"] = width+"px";
3642			 
3643		}
3644		 
3645		g_objStrip.css(objCssStrip);
3646		g_objStripInner.css(objCssInner);				
3647	}
3648	
3649	
3650	
3651	/**
3652	 * scroll by some number
3653	 * .
3654	 */
3655	function scrollBy(scrollStep){
3656		
3657		var innerPos = t.getInnerStripPos();
3658		var finalPos = innerPos + scrollStep;
3659		
3660		finalPos = t.fixInnerStripLimits(finalPos);
3661		
3662		t.positionInnerStrip(finalPos, true);		
3663	}
3664	
3665
3666	/**
3667	 * scroll to thumb from min. (left or top) position
3668	 */
3669	function scrollToThumbMin(objThumb){
3670		
3671		var objThumbPos = getThumbPos(objThumb);
3672		
3673		var scrollPos = objThumbPos.min * -1;
3674		scrollPos = t.fixInnerStripLimits(scrollPos);
3675
3676		t.positionInnerStrip(scrollPos, true);
3677	}
3678	
3679	
3680	/**
3681	 * scroll to thumb from max. (right or bottom) position
3682	 */
3683	function scrollToThumbMax(objThumb){
3684		
3685		var objThumbPos = getThumbPos(objThumb);		
3686		
3687		var scrollPos = objThumbPos.max * -1 + g_sizes.stripSize;
3688		scrollPos = t.fixInnerStripLimits(scrollPos);
3689		
3690		t.positionInnerStrip(scrollPos, true);
3691	}
3692
3693	
3694	/**
3695	 * scroll to some thumbnail
3696	 */
3697	function scrollToThumb(objThumb){
3698		
3699		if(isStripMovingEnabled() == false)
3700			return(false);
3701		
3702		var objBounds = getThumbsInsideBounds();
3703		
3704		var objThumbPos = getThumbPos(objThumb);
3705		
3706		if(objThumbPos.min < objBounds.minPosThumbs){			
3707			
3708			var prevThumb = objThumb.prev();
3709			if(prevThumb.length)
3710				scrollToThumbMin(prevThumb);
3711			else 
3712				scrollToThumbMin(objThumb);				
3713			
3714		}else if(objThumbPos.max > objBounds.maxPosThumbs){			
3715			
3716			var nextThumb = objThumb.next();
3717			if(nextThumb.length)
3718				scrollToThumbMax(nextThumb);
3719			else
3720				scrollToThumbMax(objThumb);
3721				
3722		}
3723		
3724	}
3725	
3726	/**
3727	 * scroll to selected thumb
3728	 */
3729	function scrollToSelectedThumb(){
3730		
3731		var selectedItem = g_gallery.getSelectedItem();
3732		if(selectedItem == null)
3733			return(true);
3734		
3735		var objThumb = selectedItem.objThumbWrapper;
3736		if(objThumb)
3737			scrollToThumb(objThumb);
3738		
3739	}
3740	
3741	
3742	
3743	/**
3744	 * check that the inner strip off the limits position, and reposition it if there is a need
3745	 */
3746	function checkAndRepositionInnerStrip(){
3747		if(isStripMovingEnabled() == false)
3748			return(false);
3749		
3750		var pos = t.getInnerStripPos();
3751		
3752		var posFixed = t.fixInnerStripLimits(pos);
3753				
3754		if(pos != posFixed)
3755			t.positionInnerStrip(posFixed, true);
3756	}
3757	
3758	
3759	/**
3760	 * enable / disable controls according inner width (move enabled).
3761	 */
3762	function checkControlsEnableDisable(){
3763		
3764		var isMovingEndbled = isStripMovingEnabled();
3765		
3766		if(isMovingEndbled == true){
3767			
3768			if(g_aviaControl)
3769				g_aviaControl.enable();
3770			
3771			if(g_touchThumbsControl)
3772				g_touchThumbsControl.enable();
3773			
3774		}else{
3775			
3776			if(g_aviaControl)
3777				g_aviaControl.disable();
3778			
3779			if(g_touchThumbsControl)
3780				g_touchThumbsControl.disable();
3781			
3782		}
3783		
3784	}
3785	
3786	/**
3787	 * align inner strip according the options
3788	 */
3789	function alignInnerStrip(){
3790		
3791		if(isStripMovingEnabled())
3792			return(false);
3793		
3794		if(g_isVertical == false)
3795			g_functions.placeElement(g_objStripInner, g_options.strip_thumbs_align, 0);
3796		else
3797			g_functions.placeElement(g_objStripInner, 0, g_options.strip_thumbs_align);
3798			
3799	}
3800	
3801	
3802	function ___________EVENTS___________(){};
3803	
3804	/**
3805	 * on thumb click event. Select the thumb
3806	 */
3807	function onThumbClick(objThumb){
3808
3809		//cancel click event only if passed significant movement
3810		if(t.isTouchMotionActive()){
3811
3812			var isSignificantPassed = g_touchThumbsControl.isSignificantPassed();
3813			if(isSignificantPassed == true)
3814				return(true);
3815		}
3816
3817		//run select item operation
3818		var objItem = g_thumbs.getItemByThumb(objThumb);
3819
3820		g_gallery.selectItem(objItem);
3821	}
3822	
3823	
3824	/**
3825	 * on some thumb placed, run the resize, but with time passed
3826	 */
3827	function onThumbPlaced(){
3828		
3829		clearTimeout(g_temp.handle);
3830		
3831		g_temp.handle = setTimeout(function(){
3832			
3833			positionThumbs();
3834			
3835		},50);
3836			
3837		
3838	}
3839	
3840	/**
3841	 * on item change
3842	 */
3843	function onItemChange(){
3844
3845		var objItem = g_gallery.getSelectedItem();
3846		g_thumbs.setThumbSelected(objItem.objThumbWrapper);
3847		scrollToThumb(objItem.objThumbWrapper);
3848	}
3849	
3850	
3851	/**
3852	 * init panel events
3853	 */
3854	function initEvents(){
3855		
3856		g_thumbs.initEvents();
3857
3858		var objThumbs = g_objStrip.find(".ug-thumb-wrapper");
3859				
3860		objThumbs.on("click touchend", function(event){
3861			
3862			var clickedThumb = jQuery(this);
3863			onThumbClick(clickedThumb);
3864		});
3865		
3866		//on item change, make the thumb selected
3867		g_objGallery.on(g_gallery.events.ITEM_CHANGE, onItemChange);
3868
3869		
3870		//position thumbs after each load on non fixed mode
3871		if(g_temp.isNotFixedThumbs){
3872			
3873			jQuery(g_thumbs).on(g_thumbs.events.AFTERPLACEIMAGE, onThumbPlaced);
3874			
3875		}
3876		
3877	}
3878	
3879	
3880	/**
3881	 * destroy the strip panel events
3882	 */
3883	this.destroy = function(){
3884		
3885		var objThumbs = g_objStrip.find(".ug-thumb-wrapper");
3886		
3887		objThumbs.off("click");
3888		objThumbs.off("touchend");
3889		g_objGallery.off(g_gallery.events.ITEM_CHANGE);
3890
3891		jQuery(g_thumbs).off(g_thumbs.events.AFTERPLACEIMAGE);
3892		
3893		if(g_touchThumbsControl)
3894			g_touchThumbsControl.destroy();
3895		
3896		if(g_aviaControl)
3897			g_aviaControl.destroy();
3898		
3899		g_thumbs.destroy();
3900	}
3901	
3902	
3903	function ____________GETTERS___________(){};
3904		
3905
3906	/**
3907	 * check if the inner width is more then strip width
3908	 */
3909	function isStripMovingEnabled(){
3910		
3911		if(g_sizes.stripInnerSize > g_sizes.stripActiveSize)
3912			return(true);
3913		else
3914			return(false);
3915		
3916	}
3917	
3918	
3919	/**
3920	 * get bounds, if the thumb not in them, it need to be scrolled
3921	 * minPosThumbs, maxPosThumbs - the min and max position that the thumbs should be located to be visible
3922	 */
3923	function getThumbsInsideBounds(){
3924		var obj = {};
3925		var innerPos = t.getInnerStripPos();
3926		
3927		//the 1 is gap that avoid exact bounds
3928		obj.minPosThumbs = innerPos * -1 + 1;				
3929		obj.maxPosThumbs = innerPos * -1 + g_sizes.stripSize - 1;		
3930		
3931		return(obj);
3932	}
3933	
3934	
3935	/**
3936	 * get thumb position according the orientation in the inner strip
3937	 */
3938	function getThumbPos(objThumb){
3939		
3940		var objReturn = {};
3941		
3942		var objPos = objThumb.position();
3943		
3944		if(g_isVertical == false){
3945			objReturn.min = objPos.left;
3946			objReturn.max = objPos.left + g_sizes.thumbSize;
3947		}else{
3948			objReturn.min = objPos.top;
3949			objReturn.max = objPos.top + g_sizes.thumbSize;
3950		}
3951
3952		
3953		return(objReturn);
3954	}
3955	
3956	
3957	
3958	
3959	this.________EXTERNAL_GENERAL___________ = function(){};
3960
3961	/**
3962	 * init function for avia controls
3963	 */
3964	this.init = function(gallery, customOptions){
3965		
3966		initStrip(gallery, customOptions);
3967	}
3968	
3969	
3970	/**
3971	 * set html and properties
3972	 */	
3973	this.run = function(){
3974		runStrip();
3975	}
3976	
3977	
3978	
3979	
3980	/**
3981	* position inner strip on some pos according the orientation
3982	*/
3983	this.positionInnerStrip = function(pos, isAnimate){
3984		
3985		if(isAnimate === undefined)
3986			var isAnimate = false;
3987		
3988		if(g_isVertical == false)
3989			var objPosition = {"left": pos + "px"};
3990		else
3991			var objPosition = {"top": pos + "px"};
3992		
3993		if(isAnimate == false){		//normal position
3994			
3995			g_objStripInner.css(objPosition);
3996			t.triggerStripMoveEvent();
3997		}
3998		else{		//position with animation
3999			
4000			t.triggerStripMoveEvent();
4001			
4002			g_objStripInner.stop(true).animate(objPosition ,{
4003				duration: g_options.strip_scroll_to_thumb_duration,
4004				easing: g_options.strip_scroll_to_thumb_easing,
4005				queue: false,
4006				progress:function(){t.triggerStripMoveEvent()},
4007				always: function(){t.triggerStripMoveEvent()}
4008			});					
4009			
4010		}
4011		
4012	}
4013
4014	/**
4015	 * trigger event - on strip move
4016	 */
4017	this.triggerStripMoveEvent = function(){
4018		
4019		//trigger onstripmove event
4020		jQuery(t).trigger(t.events.STRIP_MOVE);
4021		
4022	}
4023	
4024		
4025	
4026	/**
4027	 * return true if the touch animation or dragging is active
4028	 */
4029	this.isTouchMotionActive = function(){
4030		if(!g_touchThumbsControl)
4031			return(false);
4032		
4033		var isActive = g_touchThumbsControl.isTouchActive();
4034		
4035		return(isActive);
4036	}
4037	
4038	
4039	/**
4040	 * check if thmb item visible, means inside the visible part of the inner strip
4041	 */
4042	this.isItemThumbVisible = function(objItem){
4043		
4044		var objThumb = objItem.objThumbWrapper;
4045		var thumbPos = objThumb.position();
4046		
4047		var posMin = t.getInnerStripPos() * -1;
4048		
4049		if(g_isVertical == false){
4050			var posMax = posMin + g_sizes.stripSize;
4051			var thumbPosMin = thumbPos.left;
4052			var thumbPosMax = thumbPos.left + objThumb.width();			
4053		}else{
4054			var posMax = posMin + g_sizes.stripSize;
4055			var thumbPosMin = thumbPos.top;
4056			var thumbPosMax = thumbPos.top + objThumb.height();			
4057		}
4058				
4059		var isVisible = false;
4060		if(thumbPosMax >= posMin && thumbPosMin <= posMax)
4061			isVisible = true;
4062		
4063		return(isVisible);
4064	}
4065	
4066	/**
4067	 * get inner strip position according the orientation
4068	 */
4069	this.getInnerStripPos = function(){
4070		
4071		if(g_isVertical == false)			
4072			return g_objStripInner.position().left;
4073		else
4074			return g_objStripInner.position().top;
4075	}
4076	
4077	
4078	/**
4079	 * get inner strip limits
4080	 */
4081	this.getInnerStripLimits = function(){
4082		
4083		var output = {};
4084		
4085		if(g_isVertical == false)
4086			output.maxPos = g_options.strip_padding_left;
4087		else
4088			output.maxPos = g_options.strip_padding_top;
4089		
4090		//debugLine(g_sizes.stripActiveSize);
4091		
4092		output.minPos = -(g_sizes.stripInnerSize - g_sizes.stripActiveSize);
4093		
4094		return(output);
4095	}
4096
4097	
4098	/**
4099	 * fix inner position by check boundaries limit
4100	 */
4101	this.fixInnerStripLimits = function(distPos){
4102		
4103		var minPos;
4104		
4105		var objLimits = t.getInnerStripLimits();
4106		
4107		if(distPos > objLimits.maxPos)
4108			distPos = objLimits.maxPos;
4109		
4110		if(distPos < objLimits.minPos)
4111			distPos = objLimits.minPos;
4112		
4113		return(distPos);
4114	}
4115	
4116	
4117	
4118	/**
4119	 * scroll left or down
4120	 */
4121	this.scrollForeward = function(){
4122		scrollBy(-g_sizes.stripSize);
4123	}
4124	
4125	
4126	/**
4127	 * scroll left or down
4128	 */
4129	this.scrollBack = function(){
4130				
4131		scrollBy(g_sizes.stripSize);
4132	}
4133	
4134	
4135	this.________EXTERNAL_SETTERS___________ = function(){};
4136
4137	
4138	/**
4139	 * set the options of the strip
4140	 */
4141	this.setOptions = function(objOptions){
4142		
4143		g_options = jQuery.extend(g_options, objOptions);
4144		
4145		g_thumbs.setOptions(objOptions);
4146		
4147		onAfterSetOptions();
4148	}
4149	
4150	
4151	/**
4152	 * set size of the strip
4153	 * the height size is set automatically from options
4154	 */
4155	this.setSizeVertical = function(height){
4156		
4157		 if(g_isVertical == false){
4158			 throw new Error("setSizeVertical error, the strip size is not vertical");
4159			 return(false);
4160		 }
4161		
4162		 var width = g_sizes.thumbSecondSize;
4163		
4164		 var objCssStrip = {};
4165		 objCssStrip["width"] = width+"px";
4166		 objCssStrip["height"] = height+"px";
4167		 
4168		 g_objStrip.css(objCssStrip);
4169
4170		 storeStripSize(height);
4171		 
4172		 //set inner strip params
4173		 var objCssInner = {};
4174		 objCssInner["width"] = width+"px";
4175		 objCssInner["left"] = "0px";
4176		 objCssInner["top"] = "0px";
4177		 
4178		 g_objStripInner.css(objCssInner);
4179		 
4180		 g_temp.is_placed = true;
4181		 
4182		 checkControlsEnableDisable();
4183	}
4184
4185	
4186	/**
4187	 * set size of the strip
4188	 * the height size is set automatically from options
4189	 */
4190	this.setSizeHorizontal = function(width){
4191				
4192		 if(g_isVertical == true){
4193			 throw new Error("setSizeHorizontal error, the strip size is not horizontal");
4194			 return(false);
4195		 }
4196		
4197		var height = g_sizes.thumbSecondSize + g_options.strip_padding_top + g_options.strip_padding_bottom;
4198		
4199		var objCssStrip = {};
4200		objCssStrip["width"] = width+"px";
4201		objCssStrip["height"] = height+"px";
4202		 
4203		g_objStrip.css(objCssStrip);
4204		
4205		storeStripSize(width);
4206		
4207		var innerLeft = g_options.strip_padding_left;
4208		
4209		 //set inner strip params
4210		 var objCssInner = {};
4211		 objCssInner["height"] = height+"px";
4212		 objCssInner["left"] = innerLeft + "px";
4213		 objCssInner["top"] = "0px";
4214		 
4215		 g_objStripInner.css(objCssInner);
4216		 
4217		 g_temp.is_placed = true;
4218		
4219		 checkControlsEnableDisable();
4220	}
4221	
4222	
4223	/**
4224	 * set position of the strip
4225	 */
4226	this.setPosition = function(left, top, offsetLeft, offsetTop){
4227		g_functions.placeElement(g_objStrip, left, top, offsetLeft, offsetTop);		
4228	}
4229	
4230	
4231	/**
4232	 * resize the panel according the orientation
4233	 */
4234	this.resize = function(newSize){
4235		
4236		if(g_isVertical == false){
4237			
4238			g_objStrip.width(newSize);
4239			g_sizes.stripActiveSize = newSize - g_options.strip_padding_left - g_options.strip_padding_right;
4240
4241		}else{
4242			g_objStrip.height(newSize);
4243			g_sizes.stripActiveSize = newSize - g_options.strip_padding_top - g_options.strip_padding_bottom;
4244		}
4245		
4246		storeStripSize(newSize);
4247		
4248		checkControlsEnableDisable();
4249		
4250		checkAndRepositionInnerStrip();
4251		
4252		alignInnerStrip();
4253		
4254		scrollToSelectedThumb();
4255	}
4256	
4257	
4258	/**
4259	 * set the thumb unselected state
4260	 */
4261	this.setThumbUnselected = function(objThumbWrapper){
4262		
4263		g_thumbs.setThumbUnselected(objThumbWrapper);
4264		
4265	}
4266	
4267	
4268	/**
4269	 * set custom thumbs
4270	 */
4271	this.setCustomThumbs = function(funcSetHtml){
4272		
4273		g_thumbs.setCustomThumbs(funcSetHtml);
4274		
4275	}
4276	
4277	
4278	
4279	
4280	this.________EXTERNAL_GETTERS___________ = function(){};
4281	
4282	/**
4283	 * get objects
4284	 */	
4285	this.getObjects = function(){
4286		
4287		var thumbsOptions = g_thumbs.getOptions();
4288		var commonOpitions = jQuery.extend(g_options, thumbsOptions);
4289		
4290		var obj = {
4291			g_gallery: g_gallery,
4292			g_objGallery: g_objGallery,
4293			g_objWrapper:g_objWrapper,
4294			g_arrItems:g_arrItems,
4295			g_objStrip : g_objStrip,
4296			g_objStripInner : g_objStripInner,
4297			g_aviaControl:g_aviaControl,
4298			g_touchThumbsControl:g_touchThumbsControl,
4299			isVertical: g_isVertical,
4300			g_options: commonOpitions,
4301			g_thumbs: g_thumbs
4302		};
4303		
4304		return(obj);
4305	}
4306	
4307	
4308	/**
4309	 * get thumbs onject
4310	 */
4311	this.getObjThumbs = function(){
4312		
4313		return(g_thumbs);
4314	}
4315	
4316	
4317	/**
4318	 * get selected thumb
4319	 */
4320	this.getSelectedThumb = function(){
4321		
4322		var selectedIndex = g_gallery.getSelectedItemIndex();
4323		if(selectedIndex == -1)
4324			return(null);
4325		
4326		return g_thumbs.getThumbByIndex(selectedIndex);
4327	}
4328	
4329	
4330	/**
4331	 * get strip size and position object
4332	 */
4333	this.getSizeAndPosition = function(){
4334		
4335		var obj = g_functions.getElementSize(g_objStrip);
4336		
4337		return(obj);
4338	}
4339	
4340	/**
4341	 * get thumbs strip height
4342	 */
4343	this.getHeight = function(){
4344		
4345		var stripHeight = g_objStrip.outerHeight();
4346		
4347		return(stripHeight)
4348	}
4349	
4350	
4351	/**
4352	 * get thumbs strip width
4353	 */
4354	this.getWidth = function(){
4355		
4356		var stripWidth = g_objStrip.outerWidth();
4357		
4358		return(stripWidth);
4359	}
4360	
4361	
4362	
4363	/**
4364	 * get all stored sizes object
4365	 */
4366	this.getSizes = function(){
4367		
4368		return(g_sizes);
4369	}
4370	
4371	
4372	/**
4373	 * return if vertical orientation or not
4374	 */
4375	this.isVertical = function(){
4376		return(g_isVertical);
4377	}
4378	
4379	
4380	/**
4381	 * return if the strip is placed or not
4382	 */
4383	this.isPlaced = function(){
4384		
4385		return(g_temp.is_placed);
4386	}
4387	
4388	/**
4389	 * return if the strip moving enabled or not
4390	 */
4391	this.isMoveEnabled = function(){
4392		var isEnabled = isStripMovingEnabled();
4393		return(isEnabled);
4394	}
4395
4396}
4397
4398
4399/**
4400 * touch thumbs control class
4401 * addon to strip gallery
4402 */
4403function UGTouchThumbsControl(){
4404	
4405	var g_parent, g_gallery, g_objGallery, g_objects;
4406	var g_objStrip, g_objStripInner, g_options, g_isVertical;
4407	var g_functions = new UGFunctions();
4408	
4409	//service variables	
4410	var g_serviceParams = {			
4411		touch_portion_time:200,					//the time in ms that the potion is counts for continue touch movement
4412		thumb_touch_slowFactor:0,				//set from user
4413		minDeltaTime: 70,						//don't alow portion less then the minTime
4414		minPath: 10,							//if less then this path, dont' continue motion
4415		limitsBreakAddition: 30,				//the limits break addition for second return animation
4416		returnAnimateSpeed: 500,				//the speed of return animation
4417		animationEasing: "easeOutCubic",		//animation easing function
4418		returnAnimationEasing: "easeOutCubic"	//return animation easing function
4419	};
4420	
4421	
4422	var g_temp = {					//temp variables
4423		touch_active:false,
4424		loop_active:false,
4425		mousePos:0,
4426		innerPos:0,
4427		startPos:0,
4428		startTime:0,		
4429		lastTime:0,
4430		buttonReleaseTime:0,
4431		lastPos:0,
4432		lastPortionPos:0,
4433		lastDeltaTime:0,
4434		lastDeltaPos:0,
4435		speed:0,
4436		handle:"",
4437		touchEnabled: false, 
4438		isControlEnabled: true
4439	};
4440
4441
4442	/**
4443	 * enable the control
4444	 */
4445	this.enable = function(){
4446		g_temp.isControlEnabled = true;
4447	}
4448	
4449	
4450	/**
4451	 * disable the control
4452	 */
4453	this.disable = function(){
4454		g_temp.isControlEnabled = false;		
4455	}
4456	
4457	/**
4458	 * init function for avia controls
4459	 */
4460	this.init = function(objStrip){
4461		
4462		g_parent = objStrip;
4463		g_objects = objStrip.getObjects();
4464		
4465		g_gallery = g_objects.g_gallery;
4466		g_objGallery = g_objects.g_objGallery;	//jquery object
4467				
4468		g_objStrip = g_objects.g_objStrip;
4469		g_objStripInner = g_objects.g_objStripInner;
4470		g_options = g_objects.g_options;
4471		g_isVertical = g_objects.isVertical;
4472		
4473		setServiceParams();
4474		
4475		initEvents();
4476	}
4477	
4478	/**
4479	 * get action related variables
4480	 */
4481	function getActionVars(){
4482		
4483		var currentTime = jQuery.now();
4484
4485		var obj = {};
4486		obj.passedTime = g_temp.lastTime - g_temp.startTime;
4487		obj.lastActiveTime = currentTime - g_temp.buttonReleaseTime;
4488		obj.passedDistance = g_temp.lastPos - g_temp.startPos;
4489		obj.passedDistanceAbs = Math.abs(obj.passedDistance);
4490				
4491		return(obj);
4492	}
4493	
4494	/**
4495	 * return if passed some significant movement
4496	 */
4497	this.isSignificantPassed = function(){
4498		var objVars = getActionVars();
4499		if(objVars.passedTime > 300)
4500			return(true);
4501		
4502		if(objVars.passedDistanceAbs > 30)
4503			return(true);
4504		
4505		return(false);		
4506	}
4507	
4508	
4509	/**
4510	 * return true if the touch dragging or animate motion is active
4511	 */
4512	this.isTouchActive = function(){
4513		
4514		if(g_temp.touch_active == true)
4515			return(true);
4516			
4517		//check if still animating
4518		if(g_objStripInner.is(":animated") == true)
4519			return(true);
4520		
4521		//check if just ended, the touch active continue for a few moments.
4522		var objVars = getActionVars();
4523		if(objVars.lastActiveTime < 50) 
4524			return(true);
4525				
4526		return(false);
4527	}
4528	
4529	/**
4530	 * set service parameters from user parameters
4531	 */
4532	function setServiceParams(){
4533				
4534		//set slow factor by sensetivity of touch motion		
4535		g_serviceParams.thumb_touch_slowFactor = g_functions.normalizeSetting(0.00005, 0.01, 1, 100, g_options.strip_thumb_touch_sensetivity, true);
4536				
4537		//debugLine("slowfactor "+ g_serviceParams.thumb_touch_slowFactor);
4538	}
4539	
4540	
4541	/**
4542	 * get mouse position based on orientation
4543	 */
4544	function getMouseOrientPosition(event){
4545		
4546		if(g_isVertical == false)
4547			return(g_functions.getMousePosition(event).pageX);
4548		else
4549			return(g_functions.getMousePosition(event).pageY);			
4550	}
4551	
4552	/**
4553	 * position the strip according the touch drag diff
4554	 */
4555	function handleStripDrag(mousePos){
4556		var diff = g_temp.mousePos - mousePos;
4557		var distPos = g_temp.innerPos - diff;
4558		
4559		//make harder to drag the limits
4560		var objLimits = g_parent.getInnerStripLimits();
4561		
4562		if(distPos > objLimits.maxPos){
4563			var path = distPos - objLimits.maxPos;
4564			distPos = objLimits.maxPos + path/3;			
4565		}
4566		
4567		if(distPos < objLimits.minPos){
4568			var path = objLimits.minPos - distPos;
4569			distPos = objLimits.minPos - path/3;						
4570		}
4571		
4572		g_parent.positionInnerStrip(distPos);
4573	}
4574	
4575	
4576	/**
4577	 * store initial touch values
4578	 */
4579	function storeInitTouchValues(pagePos){
4580		var currentInnerPos = g_parent.getInnerStripPos();
4581		
4582		//remember current mouse position and inner strip position
4583		g_temp.mousePos = pagePos;
4584		g_temp.innerPos = currentInnerPos;
4585		g_temp.lastPortionPos = currentInnerPos;
4586		g_temp.lastDeltaTime = 0;
4587		g_temp.lastDeltaPos = 0;
4588		
4589		//init position and time related variables
4590		g_temp.startTime = jQuery.now();
4591		g_temp.startPos = g_temp.innerPos;
4592		
4593		g_temp.lastTime = g_temp.startTime;
4594		g_temp.lastPos = g_temp.startPos;
4595		g_temp.speed = 0;
4596	}
4597	
4598	
4599	/**
4600	 * store touch portion data
4601	 */
4602	function storeTouchPortionData(){
4603				
4604		//calc speed
4605		var currentTime = jQuery.now();
4606		var deltaTime = currentTime - g_temp.lastTime;
4607		
4608		if(deltaTime >= g_serviceParams.touch_portion_time){
4609			g_temp.lastDeltaTime = currentTime - g_temp.lastTime;
4610			if(g_temp.lastDeltaTime > g_serviceParams.touch_portion_time)
4611				g_temp.lastDeltaTime = g_serviceParams.touch_portion_time;
4612				
4613			g_temp.lastDeltaPos = g_temp.lastPos - g_temp.lastPortionPos;
4614						
4615			g_temp.lastPortionPos = g_temp.lastPos;
4616			g_temp.lastTime = currentTime;
4617			
4618		}
4619		
4620	}
4621	
4622	
4623	/**
4624	 * continue touch motion - touch motion ending.
4625	 */
4626	function continueTouchMotion(){
4627				
4628		var slowFactor = g_serviceParams.thumb_touch_slowFactor;
4629		
4630		//don't alow portion less then the minTime
4631		var minDeltaTime = g_serviceParams.minDeltaTime;
4632		
4633		//if less then this path, dont' continue motion
4634		var minPath = g_serviceParams.minPath;	
4635		
4636		var currentInnerPos = g_parent.getInnerStripPos();
4637		
4638		var currentTime = jQuery.now();
4639		var deltaTime = currentTime - g_temp.lastTime;
4640		var deltaPos = currentInnerPos - g_temp.lastPortionPos;
4641		
4642		//if time too fast, take last portion values
4643		if(deltaTime < minDeltaTime && g_temp.lastDeltaTime > 0){
4644			deltaTime = g_temp.lastDeltaTime;
4645			deltaPos = g_temp.lastDeltaPos + deltaPos;
4646		}
4647		
4648		//fix delta time
4649		if(deltaTime < minDeltaTime)
4650			deltaTime = minDeltaTime;
4651					
4652		var dir = (deltaPos > 0)?1:-1;
4653		
4654		var speed = 0;
4655		if(deltaTime > 0)
4656			speed = deltaPos / deltaTime;	
4657		
4658		var path = (speed * speed) / (slowFactor * 2) * dir;
4659		
4660		//disable path for very slow motions
4661		if(Math.abs(path) <= minPath)
4662			path = 0;
4663		
4664		
4665		var innerStripPos = g_parent.getInnerStripPos();
4666		var newPos = innerStripPos + path;	
4667		
4668		var correctPos = g_parent.fixInnerStripLimits(newPos);
4669		var objLimits = g_parent.getInnerStripLimits();
4670		
4671		//check the off the limits and return (second animation)
4672		var limitsBreakAddition = g_serviceParams.limitsBreakAddition;
4673		var doQueue = false;
4674		var returnPos = correctPos;
4675		
4676		//fix the first animation position (off the limits)
4677		if(newPos > objLimits.maxPos){
4678			doQueue = true;
4679			correctPos = limitsBreakAddition;
4680			if(newPos < limitsBreakAddition)
4681				correctPos = newPos;			
4682		}
4683				
4684		if(newPos < objLimits.minPos){
4685			doQueue = true;
4686			var maxStopPos = objLimits.minPos - limitsBreakAddition;
4687			correctPos = maxStopPos;
4688			if(newPos > maxStopPos)
4689				correctPos = newPos;
4690		}
4691				
4692		var correctPath = correctPos - innerStripPos;
4693		
4694		//set animation speed		
4695		var animateSpeed =  Math.abs(Math.round(speed / slowFactor));
4696		
4697		//fix animation speed according the paths difference
4698		if(path != 0)
4699			animateSpeed = animateSpeed * correctPath / path;		
4700		
4701		
4702		//Do first animation
4703		if(innerStripPos != correctPos){
4704			
4705			var animateProps = {"left":correctPos+"px"};
4706			if(g_isVertical == true)
4707				animateProps = {"top":correctPos+"px"};		
4708			
4709			g_objStripInner.animate(animateProps ,{
4710					duration: animateSpeed,
4711					easing: g_serviceParams.animationEasing,
4712					queue: true,
4713					progress:onAnimateProgress 
4714			});
4715						
4716		}
4717		
4718				
4719		//do second animation if off limits
4720		if(doQueue == true){
4721			var returnAnimateSpeed = g_serviceParams.returnAnimateSpeed;
4722			
4723			var returnAnimateProps = {"left":returnPos+"px"};
4724			if(g_isVertical == true)
4725				returnAnimateProps = {"top":returnPos+"px"};		
4726			
4727			
4728			g_objStripInner.animate(returnAnimateProps,{				
4729				duration: returnAnimateSpeed,
4730				easing: g_serviceParams.returnAnimationEasing,
4731				queue: true,
4732				progress:onAnimateProgress 
4733			});
4734		}
4735		
4736	}
4737	
4738	/**
4739	 * on animate progress event. store position and trigger event to gallery
4740	 */
4741	function onAnimateProgress(){
4742		g_temp.lastPos = g_parent.getInnerStripPos();
4743		g_parent.triggerStripMoveEvent();
4744	}
4745	
4746	/**
4747	 * start loop while touching strip
4748	 */
4749	function startStripTouchLoop(){
4750		
4751		if(g_temp.loop_active == true)
4752			return(true);
4753			
4754		g_temp.loop_active = true;
4755		g_temp.handle = setInterval(storeTouchPortionData,10);
4756	}
4757	
4758	
4759	/**
4760	 * end loop when not touching
4761	 */
4762	function endStripTouchLoop(event){
4763		
4764		if(g_temp.loop_active == false)
4765			return(true);
4766		
4767		if(event){
4768			var pagePos = getMouseOrientPosition(event);
4769			continueTouchMotion(pagePos);
4770		}
4771		
4772		g_temp.loop_active = false;
4773		g_temp.handle = clearInterval(g_temp.handle);
4774	}
4775	
4776	
4777	/**
4778	 * on tuch end event
4779	 */
4780	function onTouchEnd(event){
4781		
4782		if(g_temp.isControlEnabled == false)
4783			return(true);
4784				
4785		g_temp.buttonReleaseTime = jQuery.now();
4786		
4787		if(g_temp.touch_active == false){
4788			endStripTouchLoop(event);
4789			return(true);
4790		}
4791		
4792		event.preventDefault();
4793			
4794		g_temp.touch_active = false;
4795		
4796		endStripTouchLoop(event);
4797		
4798		g_objStrip.removeClass("ug-dragging");
4799		
4800	}
4801	
4802	
4803	/**
4804	 * on touch start - start the motion
4805	 * @param event
4806	 */
4807	function onTouchStart(event){
4808		
4809		if(g_temp.isControlEnabled == false)
4810			return(true);
4811		
4812		event.preventDefault();
4813		
4814		g_temp.touch_active = true;		//don't move this up
4815		
4816		var pagePos = getMouseOrientPosition(event);
4817					
4818		//stop inner animation if exist
4819		g_objStripInner.stop(true);
4820		
4821		//store initial touch values
4822		storeInitTouchValues(pagePos);
4823		startStripTouchLoop();
4824		
4825		g_objStrip.addClass("ug-dragging");
4826	}
4827	
4828	
4829	/**
4830	 * on touch move event, move the strip
4831	 */
4832	function onTouchMove(event){
4833		
4834		if(g_temp.isControlEnabled == false)
4835			return(true);		
4836		
4837		if(g_temp.touch_active == false)
4838			return(true);
4839		
4840		event.preventDefault();
4841		
4842		//detect moving without button press
4843		if(event.buttons == 0){
4844			g_temp.touch_active = false;
4845			
4846			endStripTouchLoop(event);
4847			return(true);
4848		}
4849	
4850		//store current position
4851		var pagePos = getMouseOrientPosition(event);
4852		g_temp.lastPos = g_parent.getInnerStripPos();
4853		
4854		handleStripDrag(pagePos);
4855		
4856		storeTouchPortionData();
4857		
4858	}
4859	
4860	
4861	/**
4862	 * init strip touch events
4863	 */
4864	function initEvents(){
4865		
4866		//strip mouse down - drag start
4867		g_objStrip.bind("mousedown touchstart",onTouchStart);
4868
4869		
4870		//on body mouse up - drag end
4871		jQuery(window).add("body").bind("mouseup touchend",onTouchEnd);
4872				
4873		//on body move
4874		jQuery("body").bind("mousemove touchmove", onTouchMove);
4875		
4876	}
4877	
4878	
4879	/**
4880	 * destroy the touch events
4881	 */
4882	this.destroy = function(){
4883		g_objStrip.unbind("mousedown");
4884		g_objStrip.unbind("touchstart");
4885		jQuery(window).add("body").unbind("mouseup").unbind("touchend");
4886		jQuery("body").unbind("mousemove").unbind("touchmove");
4887	}
4888}
4889
4890
4891/** -------------- Panel Base Functions ---------------------*/
4892
4893function UGPanelsBase(){
4894	
4895	var g_temp, g_panel, g_objPanel, g_options, g_objThis;
4896	var g_gallery = new UniteGalleryMain();
4897	var t = this, g_objHandle, g_objGallery;
4898	var g_functions = new UGFunctions();
4899	
4900	
4901	/**
4902	 * init the base panel
4903	 */
4904	this.init = function(gallery, g_tempArg, g_panelArg, options, g_objThisArg){
4905		g_temp = g_tempArg; 
4906		g_panel = g_panelArg;
4907		g_gallery = gallery;
4908		g_options = options;
4909		g_objThis = g_objThisArg;
4910		
4911		g_objGallery = jQuery(g_gallery);
4912	}
4913
4914	/**
4915	 * set common panels html
4916	 */
4917	this.setHtml = function(g_objPanelArg){
4918		
4919		g_objPanel = g_objPanelArg;
4920		
4921		if(g_temp.panelType == "strip")
4922			var enable_handle = g_options.strippanel_enable_handle;
4923		else
4924			var enable_handle = g_options.gridpanel_enable_handle;
4925		
4926		// add handle
4927		if (enable_handle == true) {
4928			g_objHandle = new UGPanelHandle();
4929			g_objHandle.init(g_panel, g_objPanel, g_options, g_temp.panelType, g_gallery);
4930			g_objHandle.setHtml();
4931		}
4932		
4933		
4934		//set disabled at start if exists
4935		if(g_temp.isDisabledAtStart === true){
4936			var html = "<div class='ug-overlay-disabled'></div>";
4937			g_objPanel.append(html);
4938			
4939			setTimeout(function(){
4940				g_objPanel.children(".ug-overlay-disabled").hide();
4941			}, g_temp.disabledAtStartTimeout);
4942		
4943		}
4944		
4945	}
4946	
4947	
4948	/**
4949	 * place common elements
4950	 */
4951	this.placeElements = function(){
4952		
4953		// place handle
4954		if (g_objHandle)
4955			g_objHandle.placeHandle();		
4956	}
4957	
4958	
4959	/**
4960	 * init common events
4961	 */
4962	this.initEvents = function(){
4963		
4964		// set handle events
4965		if (g_objHandle){
4966			g_objHandle.initEvents();
4967			
4968			//set on slider action events
4969			g_objGallery.on(g_gallery.events.SLIDER_ACTION_START, function(){			
4970				g_objHandle.hideHandle();
4971			});
4972			
4973			g_objGallery.on(g_gallery.events.SLIDER_ACTION_END, function(){			
4974				g_objHandle.showHandle();
4975			});
4976			
4977		}
4978		
4979	}
4980	
4981	/**
4982	 * destroy the panel events
4983	 */
4984	this.destroy = function(){
4985		
4986		if(g_objHandle){
4987			g_objHandle.destroy();
4988			g_objGallery.off(g_gallery.events.SLIDER_ACTION_START);
4989			g_objGallery.off(g_gallery.events.SLIDER_ACTION_END);
4990		}
4991		
4992	}
4993	
4994	/**
4995	 * place panel with some animation
4996	 */
4997	function placePanelAnimation(panelDest, functionOnComplete) {
4998
4999		switch (g_temp.orientation) {
5000		case "right": // vertical
5001		case "left":
5002			var objCss = {
5003				left : panelDest + "px"
5004			};
5005			break;
5006		case "top":
5007		case "bottom":
5008			var objCss = {
5009				top : panelDest + "px"
5010			};
5011			break;
5012		}
5013
5014		g_objPanel.stop(true).animate(objCss, {
5015			duration : 300,
5016			easing : "easeInOutQuad",
5017			queue : false,
5018			complete : function() {
5019				if (functionOnComplete)
5020					functionOnComplete();
5021			}
5022		});
5023
5024	}
5025	
5026	
5027	/**
5028	 * place the panel without animation
5029	 * 
5030	 * @param panelDest
5031	 */
5032	function placePanelNoAnimation(panelDest) {
5033
5034		switch (g_temp.orientation) {
5035		case "right": // vertical
5036		case "left":
5037			g_functions.placeElement(g_objPanel, panelDest, null);
5038			break;
5039		case "top":
5040		case "bottom":
5041			g_functions.placeElement(g_objPanel, null, panelDest);
5042			break;
5043		}
5044	}
5045	
5046	/**
5047	 * event on panel slide finish
5048	 */
5049	function onPanelSlideFinish() {
5050
5051		g_objThis.trigger(g_panel.events.FINISH_MOVE);
5052
5053	}
5054	
5055	
5056	/**
5057	 * open the panel
5058	 */
5059	this.openPanel = function(noAnimation) {
5060
5061		if (!noAnimation)
5062			var noAnimation = false;
5063
5064		if (g_objPanel.is(":animated"))
5065			return (false);
5066
5067		if (g_temp.isClosed == false)
5068			return (false);
5069
5070		g_temp.isClosed = false;
5071
5072		g_objThis.trigger(g_panel.events.OPEN_PANEL);
5073
5074		if (noAnimation === false)
5075			placePanelAnimation(g_temp.originalPos, onPanelSlideFinish);
5076		else {
5077
5078			placePanelNoAnimation(g_temp.originalPos);
5079			onPanelSlideFinish();
5080		}
5081
5082	}
5083
5084	
5085	/**
5086	 * close the panel (slide in)
5087	 */
5088	this.closePanel = function(noAnimation) {
5089
5090		if (!noAnimation)
5091			var noAnimation = false;
5092
5093		if (g_objPanel.is(":animated"))
5094			return (false);
5095
5096		if (g_temp.isClosed == true)
5097			return (false);
5098
5099		var panelDest = t.getClosedPanelDest();
5100
5101		g_temp.isClosed = true;
5102
5103		g_objThis.trigger(g_panel.events.CLOSE_PANEL);
5104
5105		if (noAnimation === false)
5106			placePanelAnimation(panelDest, onPanelSlideFinish);
5107		else {
5108			placePanelNoAnimation(panelDest);
5109			onPanelSlideFinish();
5110		}
5111
5112	}
5113	
5114	/**
5115	 * set the panel that it's in closed state, and set original pos for opening
5116	 * later
5117	 */
5118	this.setClosedState = function(originalPos) {
5119		
5120		g_temp.originalPos = originalPos;
5121		g_objThis.trigger(g_panel.events.CLOSE_PANEL);
5122
5123		g_temp.isClosed = true;
5124	}
5125
5126	/**
5127	 * set the panel opened state
5128	 */
5129	this.setOpenedState = function(originalPos) {
5130		g_objThis.trigger(g_panel.events.OPEN_PANEL);
5131
5132		g_temp.isClosed = false;
5133	}
5134
5135	/**
5136	 * get closed panel destanation
5137	 */
5138	this.getClosedPanelDest = function() {
5139
5140		var objPanelSize = g_functions.getElementSize(g_objPanel), panelDest;
5141
5142		switch (g_temp.orientation) {
5143		case "left":
5144			g_temp.originalPos = objPanelSize.left;
5145			panelDest = -g_temp.panelWidth;
5146			break;
5147		case "right":
5148			g_temp.originalPos = objPanelSize.left;
5149			var gallerySize = g_gallery.getSize();
5150			panelDest = gallerySize.width;
5151			break;
5152		case "top":
5153			g_temp.originalPos = objPanelSize.top;
5154			panelDest = -g_temp.panelHeight;
5155			break;
5156		case "bottom":
5157			g_temp.originalPos = objPanelSize.top;
5158			var gallerySize = g_gallery.getSize();
5159			panelDest = gallerySize.height;
5160			break;
5161		}
5162
5163		return (panelDest);
5164	}
5165
5166
5167	/**
5168	 * tells if the panel is closed
5169	 */
5170	this.isPanelClosed = function() {
5171
5172		return (g_temp.isClosed);
5173	}
5174	
5175	
5176	/**
5177	 * set the panel disabled at start, called after init before setHtml
5178	 * it's enabled again after timeout end
5179	 */
5180	this.setDisabledAtStart = function(timeout){
5181		
5182		if(timeout <= 0)
5183			return(false);
5184			
5185		g_temp.isDisabledAtStart = true;
5186		g_temp.disabledAtStartTimeout = timeout;
5187		
5188	}
5189	
5190	
5191}
5192
5193
5194/** -------------- Panel Handle object ---------------------*/
5195
5196function UGPanelHandle(){
5197	
5198	var t = this, g_objPanel, g_panel, g_objHandleTip, g_panelOptions = {};
5199	var g_functions = new UGFunctions();
5200	
5201	var g_options = {
5202			panel_handle_align: "top",		//top, middle, bottom , left, right, center - close handle tip align on the handle bar according panel orientation
5203			panel_handle_offset: 0,			//offset of handle bar according the valign
5204			panel_handle_skin: 0			//skin of the handle, if empty inherit from gallery skin
5205	};
5206	
5207	
5208	/**
5209	 * init the handle
5210	 */
5211	this.init = function(panel, objPanel, panelOptions, panelType, gallery){
5212		g_panel = panel;
5213		g_objPanel = objPanel;
5214		
5215		//set needed options
5216		switch(panelType){		
5217			case "grid":
5218				g_options.panel_handle_align = panelOptions.gridpanel_handle_align;
5219				g_options.panel_handle_offset = panelOptions.gridpanel_handle_offset;
5220				g_options.panel_handle_skin = panelOptions.gridpanel_handle_skin;
5221			break;
5222			case "strip":
5223				g_options.panel_handle_align = panelOptions.strippanel_handle_align;
5224				g_options.panel_handle_offset = panelOptions.strippanel_handle_offset;
5225				g_options.panel_handle_skin = panelOptions.strippanel_handle_skin;
5226			break;
5227			default:
5228				throw new Error("Panel handle error: wrong panel type: " + panelType);			
5229			break;
5230		}
5231		
5232		//set arrows skin:
5233		var galleryOptions = gallery.getOptions();
5234		var globalSkin = galleryOptions.gallery_skin;		
5235		if(g_options.panel_handle_skin == "")
5236			g_options.panel_handle_skin = globalSkin;
5237		
5238		
5239	}
5240	
5241	
5242	/**
5243	 * set handle html
5244	 */
5245	this.setHtml = function(){
5246		
5247		var orientation = g_panel.getOrientation();
5248				
5249		var classTip = "ug-panel-handle-tip";
5250		
5251		switch(orientation){
5252			case "right":
5253				classTip += " ug-handle-tip-left";				
5254			break;
5255			case "left":
5256				classTip += " ug-handle-tip-right";
5257			break;
5258			case "bottom":
5259				classTip += " ug-handle-tip-top";				
5260			break;
5261			case "top":
5262				classTip += " ug-handle-tip-bottom";
5263			break;
5264		}
5265		
5266		g_objPanel.append("<div class='"+classTip+" ug-skin-" + g_options.panel_handle_skin + "'></div>");
5267		g_objHandleTip = g_objPanel.children(".ug-panel-handle-tip");
5268	}
5269	
5270	
5271	/**
5272	 * remove hover state of the tip
5273	 */
5274	function removeHoverState(){
5275				
5276		g_objHandleTip.removeClass("ug-button-hover");
5277	}
5278	
5279	/**
5280	 * add closed state class
5281	 */
5282	function setClosedState(){
5283				
5284		g_objHandleTip.addClass("ug-button-closed");		
5285	}
5286	
5287	/**
5288	 * add closed state class
5289	 */
5290	function removeClosedState(){
5291		g_objHandleTip.removeClass("ug-button-closed");		
5292	}
5293
5294	/**
5295	 * on handle click, close or open panel
5296	 */
5297	function onHandleClick(event){
5298		
5299		event.stopPropagation();
5300		event.stopImmediatePropagation();
5301		
5302		if(g_functions.validateClickTouchstartEvent(event.type) == false)
5303			return(true);
5304		
5305		if(g_panel.isPanelClosed())
5306			g_panel.openPanel();
5307		else
5308			g_panel.closePanel();
5309	}
5310	
5311	/**
5312	 * init events
5313	 */
5314	this.initEvents = function(){
5315		g_functions.addClassOnHover(g_objHandleTip);
5316		g_objHandleTip.bind("click touchstart", onHandleClick);
5317		
5318		//on panel open
5319		jQuery(g_panel).on(g_panel.events.OPEN_PANEL, function(){
5320			removeHoverState();
5321			removeClosedState();
5322		});
5323		
5324		//one panel close
5325		jQuery(g_panel).on(g_panel.events.CLOSE_PANEL, function(){
5326			removeHoverState();
5327			setClosedState();
5328		});
5329		
5330	}
5331	
5332	/**
5333	 * destroy the handle panel events
5334	 */
5335	this.destroy = function(){
5336		g_functions.destroyButton(g_objHandleTip);
5337		jQuery(g_panel).off(g_panel.events.OPEN_PANEL);
5338		jQuery(g_panel).off(g_panel.events.CLOSE_PANEL);
5339	}
5340	
5341	
5342	
5343	/**
5344	 * check and fix align option, set write direction
5345	 */
5346	function checkAndFixAlign(){
5347		var orientation = g_panel.getOrientation();
5348		
5349		switch(orientation){
5350			case "right":
5351			case "left":
5352				if(g_options.panel_handle_align != "top" && g_options.panel_handle_align != "bottom")
5353					g_options.panel_handle_align = "top";
5354			break;
5355			case "bottom":
5356				if(g_options.panel_handle_align != "left" && g_options.panel_handle_align != "right")
5357					g_options.panel_handle_align = "left";
5358			break;
5359			case "top":
5360				if(g_options.panel_handle_align != "left" && g_options.panel_handle_align != "right")
5361					g_options.panel_handle_align = "right";				
5362			break;
5363		}		
5364		
5365	}
5366	
5367	
5368	/**
5369	 * place the panel
5370	 */
5371	this.placeHandle = function(){
5372		var handleSize = g_functions.getElementSize(g_objHandleTip);
5373		
5374		checkAndFixAlign();
5375				
5376		var orientation = g_panel.getOrientation();
5377		
5378		switch(orientation){
5379			case "left":
5380				g_functions.placeElement(g_objHandleTip, "right", g_options.panel_handle_align, -handleSize.width);
5381			break;
5382			case "right":
5383				g_functions.placeElement(g_objHandleTip, -handleSize.width, g_options.panel_handle_align, 0 ,g_options.panel_handle_offset);
5384			break;
5385			case "top":
5386				g_functions.placeElement(g_objHandleTip, g_options.panel_handle_align, "bottom", g_options.panel_handle_offset, -handleSize.height);
5387			break;
5388			case "bottom":
5389				g_functions.placeElement(g_objHandleTip, g_options.panel_handle_align, "top", g_options.panel_handle_offset, -handleSize.height);
5390			break;
5391			default:
5392				throw new Error("Wrong panel orientation: " + orientation);
5393			break;
5394		}
5395		
5396	}
5397	
5398	/**
5399	 * hide the handle
5400	 */
5401	this.hideHandle = function(){
5402		
5403		if(g_objHandleTip.is(":visible") == true)
5404			g_objHandleTip.hide();
5405	
5406	}
5407	
5408	/**
5409	 * show the handle
5410	 */
5411	this.showHandle = function(){
5412		
5413		if(g_objHandleTip.is(":visible") == false)
5414			g_objHandleTip.show();
5415		
5416	}
5417	
5418	
5419}
5420
5421/**
5422 * grid panel class addon to grid gallery
5423 */
5424function UGStripPanel() {
5425
5426	var t = this, g_objThis = jQuery(this);
5427	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objWrapper, g_objPanel;
5428	var g_functions = new UGFunctions(), g_objStrip = new UGThumbsStrip(), g_panelBase = new UGPanelsBase();
5429	var g_objButtonNext, g_objButtonPrev;
5430
5431	this.events = {
5432		FINISH_MOVE : "gridpanel_move_finish", // called after close or open panel (slide finish).
5433		OPEN_PANEL : "open_panel", 			   // called before opening the panel.
5434		CLOSE_PANEL : "close_panel" 		   // called before closing the panel.
5435	};
5436
5437	var g_options = {
5438
5439		strippanel_vertical_type : false, // true, false - specify if the panel is vertical or horizonatal type
5440
5441		strippanel_padding_top : 8,       // space from top of the panel
5442		strippanel_padding_bottom : 8,    // space from bottom of the panel
5443
5444		strippanel_padding_left : 0,      // space from left of the panel
5445		strippanel_padding_right : 0,     // space from right of the panel
5446
5447		strippanel_enable_buttons : true, // enable buttons from the sides of the panel
5448		strippanel_buttons_skin : "",     // skin of the buttons, if empty inherit from gallery skin
5449										  
5450		strippanel_padding_buttons : 2,   // padding between the buttons and the panel
5451
5452		strippanel_buttons_role : "scroll_strip",   // scroll_strip, advance_item - the role of the side buttons
5453		
5454		strippanel_enable_handle : true,  // enable grid handle
5455		strippanel_handle_align : "top",  // top, middle, bottom , left, right, center - close handle tip align on the handle bar according panel orientation
5456		strippanel_handle_offset : 0, 	  // offset of handle bar according the valign
5457										
5458		strippanel_handle_skin : "", 	  // skin of the handle, if empty inherit  from gallery skin
5459
5460		strippanel_background_color : ""  // background color of the strip wrapper, if not set, it will be taken from the css
5461		
5462	};
5463
5464	var g_defaults_vertical = {
5465		strip_vertical_type : true,
5466		strippanel_padding_left : 8,
5467		strippanel_padding_right : 8,
5468		strippanel_padding_top : 0,
5469		strippanel_padding_bottom : 0
5470	};
5471
5472	var g_defaults_no_buttons = {
5473		strippanel_padding_left : 8,
5474		strippanel_padding_right : 8,
5475		strippanel_padding_top : 8,
5476		strippanel_padding_bottom : 8
5477	};
5478
5479	var g_temp = {
5480		panelType: "strip",
5481		panelWidth : 0,
5482		panelHeight : 0,
5483		isEventsInited : false,
5484		isClosed : false,
5485		orientation : null,
5486		originalPos : null,
5487		isFirstRun : true
5488	};
5489
5490	/**
5491	 * init the panel
5492	 */
5493	function initPanel(gallery, customOptions) {
5494		g_gallery = gallery;
5495
5496		g_objGallery = jQuery(g_gallery);
5497
5498		g_options = jQuery.extend(g_options, customOptions);
5499
5500		var repeatCustomOptions = false;
5501
5502		if (g_options.strippanel_vertical_type == true) {
5503			g_options = jQuery.extend(g_options, g_defaults_vertical);
5504			repeatCustomOptions = true;
5505		}
5506
5507		if (g_options.strippanel_enable_buttons == false) {
5508			g_options = jQuery.extend(g_options, g_defaults_no_buttons);
5509			repeatCustomOptions = true;
5510		}
5511
5512		if (repeatCustomOptions == true)
5513			g_options = jQuery.extend(g_options, customOptions); // do the
5514		
5515		
5516		// set arrows skin:
5517		var galleryOptions = g_gallery.getOptions();
5518		var globalSkin = galleryOptions.gallery_skin;
5519		if (g_options.strippanel_buttons_skin == "")
5520			g_options.strippanel_buttons_skin = globalSkin;
5521
5522		g_objWrapper = g_gallery.getElement();
5523		
5524		//init the base panel object:
5525		g_panelBase.init(g_gallery, g_temp, t, g_options, g_objThis);
5526		
5527		//init thumbs strip
5528		g_objStrip = new UGThumbsStrip();
5529		g_objStrip.init(g_gallery, g_options);
5530		
5531	}
5532
5533	
5534	/**
5535	 * validate panel before run
5536	 */
5537	function validatePanelBeforeRun() {
5538		
5539		if (g_options.strippanel_vertical_type == false) { // horizontal
5540															// validate
5541			if (g_temp.panelWidth == 0) {
5542				throw new Error(
5543						"Strip panel error: The width not set, please set width");
5544				return (false);
5545			}
5546
5547		} else { // vertical validate
5548
5549			if (g_temp.panelHeight == 0) {
5550				throw new Error(
5551						"Strip panel error: The height not set, please set height");
5552				return (false);
5553			}
5554
5555		}
5556
5557		// validate orientation
5558		if (g_temp.orientation == null) {
5559			throw new Error(
5560					"Wrong orientation, please set panel orientation before run");
5561			return (false);
5562		}
5563
5564		return (true);
5565	}
5566
5567	/**
5568	 * run the panel
5569	 */
5570	function runPanel() {
5571
5572		// validation
5573		if (g_temp.isFirstRun == true && validatePanelBeforeRun() == false)
5574			return (false);
5575
5576		g_objStrip.run();
5577		
5578		setElementsSize();
5579		placeElements();
5580				
5581		initEvents();
5582
5583		g_temp.isFirstRun = false;
5584
5585		checkSideButtons();
5586	}
5587
5588	/**
5589	 * set panel html
5590	 */
5591	function setPanelHtml(parentContainer) {
5592		
5593		if (!parentContainer)
5594			var parentContainer = g_objWrapper;
5595
5596		// add panel wrapper
5597		parentContainer.append("<div class='ug-strip-panel'></div>");
5598
5599		g_objPanel = parentContainer.children('.ug-strip-panel');
5600
5601		// add arrows:
5602		if (g_options.strippanel_enable_buttons == true) {
5603
5604			var arrowPrevClass = "ug-strip-arrow-left";
5605			var arrowNextClass = "ug-strip-arrow-right";
5606			if (g_options.strippanel_vertical_type == true) {
5607				arrowPrevClass = "ug-strip-arrow-up";
5608				arrowNextClass = "ug-strip-arrow-down";
5609			}
5610
5611			g_objPanel.append("<div class='ug-strip-arrow " + arrowPrevClass
5612					+ " ug-skin-" + g_options.strippanel_buttons_skin
5613					+ "'><div class='ug-strip-arrow-tip'></div></div>");
5614			g_objPanel.append("<div class='ug-strip-arrow " + arrowNextClass
5615					+ " ug-skin-" + g_options.strippanel_buttons_skin
5616					+ "'><div class='ug-strip-arrow-tip'></div></div>");
5617
5618		}
5619		
5620		g_panelBase.setHtml(g_objPanel);
5621		
5622		g_objStrip.setHtml(g_objPanel);
5623		
5624		if (g_options.strippanel_enable_buttons == true) {
5625			g_objButtonPrev = g_objPanel.children("." + arrowPrevClass);
5626			g_objButtonNext = g_objPanel.children("." + arrowNextClass);
5627		}
5628
5629		setHtmlProperties();
5630	}
5631
5632	/**
5633	 * set html properties according the options
5634	 */
5635	function setHtmlProperties() {
5636
5637		// set panel background color
5638		if (g_options.strippanel_background_color != "")
5639			g_objPanel.css("background-color",
5640					g_options.strippanel_background_color);
5641
5642	}
5643
5644	/**
5645	 * set elements size horizontal type
5646	 */
5647	function setElementsSize_hor() {
5648		
5649		// get strip height
5650		var stripHeight = g_objStrip.getHeight();
5651		var panelWidth = g_temp.panelWidth;
5652
5653		// set buttons height
5654		if (g_objButtonNext) {
5655			g_objButtonPrev.height(stripHeight);
5656			g_objButtonNext.height(stripHeight);
5657
5658			// arrange buttons tip
5659			var prevTip = g_objButtonPrev.children(".ug-strip-arrow-tip");
5660			g_functions.placeElement(prevTip, "center", "middle");
5661
5662			var nextTip = g_objButtonNext.children(".ug-strip-arrow-tip");
5663			g_functions.placeElement(nextTip, "center", "middle");
5664		}
5665
5666		// set panel height
5667		var panelHeight = stripHeight + g_options.strippanel_padding_top
5668				+ g_options.strippanel_padding_bottom;
5669
5670		// set panel size
5671		g_objPanel.width(panelWidth);
5672		g_objPanel.height(panelHeight);
5673
5674		g_temp.panelHeight = panelHeight;
5675
5676		// set strip size
5677		var stripWidth = panelWidth - g_options.strippanel_padding_left	- g_options.strippanel_padding_right;
5678
5679		if (g_objButtonNext) {
5680			var buttonWidth = g_objButtonNext.outerWidth();
5681			stripWidth = stripWidth - buttonWidth * 2 - g_options.strippanel_padding_buttons * 2;
5682		}
5683
5684		g_objStrip.resize(stripWidth);
5685	}
5686
5687	/**
5688	 * set elements size vertical type
5689	 */
5690	function setElementsSize_vert() {
5691				
5692		// get strip width
5693		var stripWidth = g_objStrip.getWidth();
5694		var panelHeight = g_temp.panelHeight;
5695		
5696		// set buttons height
5697		if (g_objButtonNext) {
5698			g_objButtonPrev.width(stripWidth);
5699			g_objButtonNext.width(stripWidth);
5700
5701			// arrange buttons tip
5702			var prevTip = g_objButtonPrev.children(".ug-strip-arrow-tip");
5703			g_functions.placeElement(prevTip, "center", "middle");
5704
5705			var nextTip = g_objButtonNext.children(".ug-strip-arrow-tip");
5706			g_functions.placeElement(nextTip, "center", "middle");
5707		}
5708
5709		// set panel width
5710		var panelWidth = stripWidth + g_options.strippanel_padding_left
5711				+ g_options.strippanel_padding_right;
5712
5713		// set panel size
5714		g_objPanel.width(panelWidth);
5715		g_objPanel.height(panelHeight);
5716
5717		g_temp.panelWidth = panelWidth;
5718
5719		// set strip size
5720		var stripHeight = panelHeight - g_options.strippanel_padding_top
5721				- g_options.strippanel_padding_bottom;
5722
5723		if (g_objButtonNext) {
5724			var buttonHeight = g_objButtonNext.outerHeight();
5725			stripHeight = stripHeight - buttonHeight * 2
5726					- g_options.strippanel_padding_buttons * 2;
5727		}
5728
5729		g_objStrip.resize(stripHeight);
5730	}
5731
5732	/**
5733	 * set elements size and place the elements
5734	 */
5735	function setElementsSize() {
5736
5737		if (g_options.strippanel_vertical_type == false)
5738			setElementsSize_hor();
5739		else
5740			setElementsSize_vert();
5741	}
5742
5743	/**
5744	 * place elements horizontally
5745	 */
5746	function placeElements_hor() {
5747
5748		// place buttons
5749		if (g_objButtonNext) {
5750			g_functions.placeElement(g_objButtonPrev, "left", "top",
5751					g_options.strippanel_padding_left,
5752					g_options.strippanel_padding_top);
5753			g_functions.placeElement(g_objButtonNext, "right", "top",
5754					g_options.strippanel_padding_right,
5755					g_options.strippanel_padding_top);
5756		}
5757
5758		var stripX = g_options.strippanel_padding_left;
5759		if (g_objButtonNext)
5760			stripX += g_objButtonNext.outerWidth()
5761					+ g_options.strippanel_padding_buttons;
5762
5763		g_objStrip.setPosition(stripX, g_options.strippanel_padding_top);
5764
5765	}
5766
5767	/**
5768	 * place elements vertically
5769	 */
5770	function placeElements_vert() {
5771
5772		// place buttons
5773		if (g_objButtonNext) {
5774			g_functions.placeElement(g_objButtonPrev, "left", "top",
5775					g_options.strippanel_padding_left,
5776					g_options.strippanel_padding_top);
5777			g_functions.placeElement(g_objButtonNext, "left", "bottom",
5778					g_options.strippanel_padding_left,
5779					g_options.strippanel_padding_bottom);
5780		}
5781
5782		var stripY = g_options.strippanel_padding_top;
5783		if (g_objButtonNext)
5784			stripY += g_objButtonNext.outerHeight()
5785					+ g_options.strippanel_padding_buttons;
5786
5787		g_objStrip.setPosition(g_options.strippanel_padding_left, stripY);
5788	}
5789
5790	/**
5791	 * place elements
5792	 */
5793	function placeElements() {
5794
5795		if (g_options.strippanel_vertical_type == false)
5796			placeElements_hor();
5797		else
5798			placeElements_vert();
5799
5800		g_panelBase.placeElements();
5801
5802	}
5803
5804
5805
5806	function __________EVENTS___________() {
5807	}
5808	;
5809
5810	/**
5811	 * on next button click
5812	 */
5813	function onNextButtonClick(objButton) {
5814
5815		if (g_functions.isButtonDisabled(objButton))
5816			return (true);
5817
5818		if (g_options.strippanel_buttons_role == "advance_item")
5819			g_gallery.nextItem();
5820		else
5821			g_objStrip.scrollForeward();
5822	}
5823
5824	/**
5825	 * on previous button click
5826	 */
5827	function onPrevButtonClick(objButton) {
5828
5829		if (g_functions.isButtonDisabled(objButton))
5830			return (true);
5831
5832		if (g_options.strippanel_buttons_role == "advance_item")
5833			g_gallery.prevItem();
5834		else
5835			g_objStrip.scrollBack();
5836	}
5837
5838	/**
5839	 * check buttons if they need to be disabled or not
5840	 */
5841	function checkSideButtons() {
5842				
5843		if (!g_objButtonNext)
5844			return (true);
5845
5846		// if the strip not movable - disable both buttons
5847		if (g_objStrip.isMoveEnabled() == false) {
5848			g_functions.disableButton(g_objButtonPrev);
5849			g_functions.disableButton(g_objButtonNext);
5850			return (true);
5851		}
5852		
5853		// check the limits
5854		var limits = g_objStrip.getInnerStripLimits();
5855		var pos = g_objStrip.getInnerStripPos();
5856		
5857		if (pos >= limits.maxPos) {
5858			g_functions.disableButton(g_objButtonPrev);
5859		} else {
5860			g_functions.enableButton(g_objButtonPrev);
5861		}
5862
5863		if (pos <= limits.minPos)
5864			g_functions.disableButton(g_objButtonNext);
5865		else
5866			g_functions.enableButton(g_objButtonNext);
5867
5868	}
5869
5870	/**
5871	 * on strip move event
5872	 */
5873	function onStripMove() {
5874		checkSideButtons();
5875	}
5876
5877	/**
5878	 * on item change event, disable or enable buttons according the images
5879	 * position
5880	 */
5881	function onItemChange() {
5882
5883		if (g_gallery.isLastItem())
5884			g_functions.disableButton(g_objButtonNext);
5885		else
5886			g_functions.enableButton(g_objButtonNext);
5887
5888		if (g_gallery.isFirstItem())
5889			g_functions.disableButton(g_objButtonPrev);
5890		else
5891			g_functions.enableButton(g_objButtonPrev);
5892
5893	}
5894
5895
5896	/**
5897	 * init panel events
5898	 */
5899	function initEvents() {
5900
5901		if (g_temp.isEventsInited == true)
5902			return (false);
5903		
5904		g_temp.isEventsInited = true;
5905		
5906		// buttons events
5907		if (g_objButtonNext) {
5908
5909			// add hove class
5910			g_functions.addClassOnHover(g_objButtonNext, "ug-button-hover");
5911			g_functions.addClassOnHover(g_objButtonPrev, "ug-button-hover");
5912
5913			// add click events
5914			g_functions.setButtonOnClick(g_objButtonPrev, onPrevButtonClick);
5915			g_functions.setButtonOnClick(g_objButtonNext, onNextButtonClick);
5916
5917			// add disable / enable buttons on strip move event
5918			if (g_options.strippanel_buttons_role != "advance_item") {
5919				
5920				jQuery(g_objStrip).on(g_objStrip.events.STRIP_MOVE, onStripMove);
5921				
5922				jQuery(g_objStrip).on(g_objStrip.events.INNER_SIZE_CHANGE, checkSideButtons);
5923				
5924				g_objGallery.on(g_gallery.events.SIZE_CHANGE, checkSideButtons);
5925				
5926			} else {
5927				var galleryOptions = g_gallery.getOptions();
5928				if (galleryOptions.gallery_carousel == false)
5929					jQuery(g_gallery).on(g_gallery.events.ITEM_CHANGE, onItemChange);
5930			}
5931
5932		}
5933
5934		g_panelBase.initEvents();
5935	}
5936	
5937	/**
5938	 * destroy the strip panel events
5939	 */
5940	this.destroy = function(){
5941		
5942		if(g_objButtonNext){
5943			g_functions.destroyButton(g_objButtonNext);
5944			g_functions.destroyButton(g_objButtonPrev);
5945			jQuery(g_objStrip).off(g_objStrip.events.STRIP_MOVE);
5946			jQuery(g_gallery).off(g_gallery.events.ITEM_CHANGE);
5947			jQuery(g_gallery).off(g_gallery.events.SIZE_CHANGE);
5948		}
5949		
5950		g_panelBase.destroy();
5951		g_objStrip.destroy();
5952	}
5953	
5954	
5955	/**
5956	 * get panel orientation
5957	 */
5958	this.getOrientation = function() {
5959
5960		return (g_temp.orientation);
5961	}
5962
5963	/**
5964	 * set panel orientation (left, right, top, bottom)
5965	 */
5966	this.setOrientation = function(orientation) {
5967
5968		g_temp.orientation = orientation;
5969	}
5970
5971	
5972	/**
5973	 * init the panel
5974	 */
5975	this.init = function(gallery, customOptions) {
5976		initPanel(gallery, customOptions);
5977	}
5978
5979	/**
5980	 * run the panel
5981	 */
5982	this.run = function() {
5983		runPanel();
5984	}
5985
5986	/**
5987	 * place panel html
5988	 */
5989	this.setHtml = function(parentContainer) {
5990		setPanelHtml(parentContainer);
5991	}
5992
5993	/**
5994	 * get the panel element
5995	 */
5996	this.getElement = function() {
5997		return (g_objPanel);
5998	}
5999
6000	/**
6001	 * get panel size object
6002	 */
6003	this.getSize = function() {
6004
6005		var objSize = g_functions.getElementSize(g_objPanel);
6006
6007		return (objSize);
6008	}
6009
6010	/**
6011	 * set panel width (for horizonal type)
6012	 */
6013	this.setWidth = function(width) {
6014
6015		g_temp.panelWidth = width;
6016
6017	}
6018
6019	/**
6020	 * set panel height (for vertical type)
6021	 */
6022	this.setHeight = function(height) {
6023
6024		g_temp.panelHeight = height;
6025
6026	}
6027
6028	/**
6029	 * resize the panel
6030	 */
6031	this.resize = function(newWidth) {
6032		t.setWidth(newWidth);
6033		setElementsSize();
6034		placeElements();
6035	}
6036	
6037	this.__________Functions_From_Base_____ = function() {}
6038	
6039	/**
6040	 * tells if the panel is closed
6041	 */
6042	this.isPanelClosed = function() {		
6043		return (g_panelBase.isPanelClosed());
6044	}
6045
6046	/**
6047	 * get closed panel destanation
6048	 */
6049	this.getClosedPanelDest = function() {
6050		return g_panelBase.getClosedPanelDest();
6051	}	
6052		
6053	/**
6054	 * open the panel
6055	 */	
6056	this.openPanel = function(noAnimation) {
6057		g_panelBase.openPanel(noAnimation);
6058	}
6059	
6060	
6061	/**
6062	 * close the panel (slide in)
6063	 */
6064	this.closePanel = function(noAnimation) {
6065		g_panelBase.closePanel(noAnimation);		
6066	}	
6067	
6068	/**
6069	 * set the panel opened state
6070	 */
6071	this.setOpenedState = function(originalPos) {
6072		g_panelBase.setOpenedState(originalPos);
6073	}
6074
6075	/**
6076	 * set the panel that it's in closed state, and set original pos for opening later
6077	 */
6078	this.setClosedState = function(originalPos) {
6079		g_panelBase.setClosedState(originalPos);	
6080	}
6081	
6082	/**
6083	 * set custom thumbs of the strip
6084	 */
6085	this.setCustomThumbs = function(funcSetHtml){
6086		
6087		g_objStrip.setCustomThumbs(funcSetHtml);
6088	
6089	}
6090	
6091	/**
6092	 * set panel disabled at start
6093	 */
6094	this.setDisabledAtStart = function(timeout){
6095		
6096		g_panelBase.setDisabledAtStart(timeout);
6097		
6098	}
6099	
6100}
6101
6102
6103/**
6104 * grid panel class
6105 * addon to grid gallery
6106 */
6107function UGGridPanel(){
6108	
6109	var t = this, g_objThis = jQuery(this);
6110	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objWrapper, g_objPanel;
6111	var g_functions = new UGFunctions();
6112	var g_objGrid = new UGThumbsGrid();
6113	var g_panelBase = new UGPanelsBase();
6114	var g_objArrowNext, g_objArrowPrev;
6115	
6116	this.events = {
6117		FINISH_MOVE: "gridpanel_move_finish",	//called after close or open panel (slide finish).
6118		OPEN_PANEL: "open_panel",				//called before opening the panel.
6119		CLOSE_PANEL: "close_panel"				//called before closing the panel.
6120	};
6121	
6122	var g_options = {
6123			gridpanel_vertical_scroll: true,			//vertical or horizontal grid scroll and arrows
6124			gridpanel_grid_align: "middle",				//top , middle , bottom, left, center, right - the align of the grid panel in the gallery 
6125			gridpanel_padding_border_top: 10,		    //padding between the top border of the panel
6126			gridpanel_padding_border_bottom: 4,			//padding between the bottom border of the panel
6127			gridpanel_padding_border_left: 10,			//padding between the left border of the panel
6128			gridpanel_padding_border_right: 10,			//padding between the right border of the panel
6129			
6130			gridpanel_arrows_skin: "",					//skin of the arrows, if empty inherit from gallery skin
6131			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.
6132			gridpanel_arrows_padding_vert: 4,			//padding between the arrows and the grid, in case of middle align, it will be minimal padding
6133			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.
6134			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"
6135			
6136			gridpanel_space_between_arrows: 20,			//space between arrows on horizontal grids only
6137			gridpanel_arrows_always_on: false,			//always show arrows even if the grid is one pane only
6138
6139			gridpanel_enable_handle: true,				//enable grid handle			
6140			gridpanel_handle_align: "top",				//top, middle, bottom , left, right, center - close handle tip align on the handle bar according panel orientation
6141			gridpanel_handle_offset: 0,					//offset of handle bar according the valign
6142			gridpanel_handle_skin: "",					//skin of the handle, if empty inherit from gallery skin
6143			
6144			gridpanel_background_color:""				//background color of the grid wrapper, if not set, it will be taken from the css
6145	};
6146	
6147	
6148	//default options for vertical scroll
6149	var g_defaultsVertical = {
6150			gridpanel_grid_align: "middle",			//top , middle , bottom
6151			gridpanel_padding_border_top: 2,		//padding between the top border of the panel
6152			gridpanel_padding_border_bottom: 2		//padding between the bottom border of the panel
6153	};
6154	
6155	//default options for horizontal type panel
6156	var g_defaultsHorType = {
6157			gridpanel_grid_align: "center"			//left, center, right			
6158	};
6159	
6160	var g_temp = {
6161		panelType: "grid",
6162		isHorType: false,
6163		arrowsVisible: false,
6164		panelHeight: 0,
6165		panelWidth: 0,
6166		originalPosX:null,
6167		isEventsInited: false,
6168		isClosed: false,
6169		orientation: null
6170	};
6171	
6172	
6173	/**
6174	 * init the grid panel
6175	 */
6176	function initGridPanel(gallery, customOptions){
6177		
6178		g_gallery = gallery;
6179		
6180		validateOrientation();
6181		
6182		//set defaults and custom options
6183		if(customOptions && customOptions.vertical_scroll){
6184			g_options.gridpanel_vertical_scroll = customOptions.vertical_scroll;			
6185		}
6186		
6187		g_options = jQuery.extend(g_options, customOptions);
6188				
6189		//set defautls for horizontal panel type
6190		if(g_temp.isHorType == true){
6191						
6192			g_options = jQuery.extend(g_options, g_defaultsHorType);
6193			g_options = jQuery.extend(g_options, customOptions);
6194					
6195		}else if(g_options.gridpanel_vertical_scroll == true){
6196
6197			//set defaults for vertical scroll
6198			g_options = jQuery.extend(g_options, g_defaultsVertical);
6199			g_options = jQuery.extend(g_options, customOptions);
6200			g_options.grid_panes_direction = "bottom";		
6201		}
6202		
6203		//set arrows skin:
6204		var galleryOptions = g_gallery.getOptions();
6205		var globalSkin = galleryOptions.gallery_skin;		
6206		if(g_options.gridpanel_arrows_skin == "")
6207			g_options.gridpanel_arrows_skin = globalSkin;
6208		
6209		
6210		//get the gallery wrapper
6211		var objects = gallery.getObjects();
6212		g_objWrapper = objects.g_objWrapper;
6213		
6214		//init the base panel object:
6215		g_panelBase.init(g_gallery, g_temp, t, g_options, g_objThis);		
6216
6217		//init the grid 
6218		g_objGrid = new UGThumbsGrid();
6219		g_objGrid.init(g_gallery, g_options);
6220
6221	}
6222	
6223	
6224	/**
6225	 * validate the orientation if exists
6226	 */
6227	function validateOrientation(){
6228		
6229		if(g_temp.orientation == null)
6230			throw new Error("Wrong orientation, please set panel orientation before run");
6231		
6232	}
6233	
6234	/**
6235	 * run the rid panel
6236	 */
6237	function runPanel(){
6238		
6239		//validate orientation
6240		validateOrientation();
6241		
6242		processOptions();
6243		
6244		g_objGrid.run();
6245		
6246		setArrows();
6247		setPanelSize();
6248		placeElements();
6249		
6250		initEvents();
6251	}
6252	
6253	
6254	/**
6255	 * set html of the grid panel
6256	 */
6257	function setHtmlPanel(){
6258		
6259		//add panel wrapper
6260		g_objWrapper.append("<div class='ug-grid-panel'></div>");
6261		
6262		g_objPanel = g_objWrapper.children('.ug-grid-panel');
6263		
6264		//add arrows:
6265		if(g_temp.isHorType){
6266			
6267			g_objPanel.append("<div class='grid-arrow grid-arrow-left-hortype ug-skin-" + g_options.gridpanel_arrows_skin + "'></div>");
6268			g_objPanel.append("<div class='grid-arrow grid-arrow-right-hortype ug-skin-" + g_options.gridpanel_arrows_skin + "'></div>");
6269			
6270			g_objArrowPrev = g_objPanel.children(".grid-arrow-left-hortype");
6271			g_objArrowNext = g_objPanel.children(".grid-arrow-right-hortype");
6272		}
6273		else if(g_options.gridpanel_vertical_scroll == false){		//horizonatl arrows
6274			g_objPanel.append("<div class='grid-arrow grid-arrow-left ug-skin-" + g_options.gridpanel_arrows_skin + "'></div>");
6275			g_objPanel.append("<div class='grid-arrow grid-arrow-right ug-skin-" + g_options.gridpanel_arrows_skin + "'></div>");
6276			
6277			g_objArrowPrev = g_objPanel.children(".grid-arrow-left");
6278			g_objArrowNext = g_objPanel.children(".grid-arrow-right");
6279			
6280		}else{		//vertical arrows
6281			g_objPanel.append("<div class='grid-arrow grid-arrow-up ug-skin-" + g_options.gridpanel_arrows_skin + "'></div>");
6282			g_objPanel.append("<div class='grid-arrow grid-arrow-down ug-skin-" + g_options.gridpanel_arrows_skin + "'></div>");
6283			
6284			g_objArrowPrev = g_objPanel.children(".grid-arrow-up");
6285			g_objArrowNext = g_objPanel.children(".grid-arrow-down");
6286		}
6287		
6288		g_panelBase.setHtml(g_objPanel);
6289		
6290		//hide the arrows
6291		g_objArrowPrev.fadeTo(0,0);
6292		g_objArrowNext.fadeTo(0,0);
6293		
6294		g_objGrid.setHtml(g_objPanel);
6295		
6296		setHtmlProperties();
6297	}
6298	
6299	
6300	/**
6301	 * set html properties according the options
6302	 */
6303	function setHtmlProperties(){
6304		
6305		//set panel background color
6306		if(g_options.gridpanel_background_color != "")
6307			g_objPanel.css("background-color",g_options.gridpanel_background_color);
6308	}
6309	
6310	
6311	/**
6312	 * process and fix certain options, avoid arrows and validate options
6313	 */
6314	function processOptions(){
6315		
6316		if(g_options.gridpanel_grid_align == "center")
6317			g_options.gridpanel_grid_align = "middle";
6318	}
6319	
6320		
6321	/**
6322	 * place panel with some animation
6323	 */
6324	function placePanelAnimation(panelX, functionOnComplete){
6325						
6326		var objCss  = {left: panelX + "px"};
6327		
6328		g_objPanel.stop(true).animate(objCss ,{
6329			duration: 300,
6330			easing: "easeInOutQuad",
6331			queue: false,
6332			complete: function(){
6333				if(functionOnComplete)
6334					functionOnComplete();
6335			}
6336		});
6337		
6338	}
6339	
6340		
6341	
6342	/**
6343	 * get max height of the grid according the arrows size
6344	 */
6345	function getGridMaxHeight(){
6346		
6347		//check space taken without arrows for one pane grids
6348		var spaceTaken = g_options.gridpanel_padding_border_top + g_options.gridpanel_padding_border_bottom;
6349		var maxGridHeight = g_temp.panelHeight - spaceTaken;
6350		
6351		if(g_options.gridpanel_arrows_always_on == false){
6352			var numPanes = g_objGrid.getNumPanesEstimationByHeight(maxGridHeight);
6353			if(numPanes == 1)
6354				return(maxGridHeight);
6355		}
6356		
6357		//count the size with arrows
6358		var arrowsSize = g_functions.getElementSize(g_objArrowNext);
6359		var arrowsHeight = arrowsSize.height;
6360		
6361		var spaceTaken = arrowsHeight + g_options.gridpanel_arrows_padding_vert;
6362		
6363		if(g_options.gridpanel_vertical_scroll == true)	//in case of 2 arrows multiply by 2
6364			spaceTaken *= 2;
6365				
6366		spaceTaken += g_options.gridpanel_padding_border_top + g_options.gridpanel_padding_border_bottom;
6367		
6368		maxGridHeight = g_temp.panelHeight - spaceTaken;			
6369		
6370		return(maxGridHeight);
6371	}
6372	
6373	
6374	/**
6375	 * get grid maximum width
6376	 */
6377	function getGridMaxWidth(){
6378				
6379		//check space taken without arrows for one pane grids
6380		var spaceTaken = g_options.gridpanel_padding_border_left + g_options.gridpanel_padding_border_right;
6381				
6382		var maxGridWidth = g_temp.panelWidth - spaceTaken;
6383		
6384		if(g_options.gridpanel_arrows_always_on == false){
6385			var numPanes = g_objGrid.getNumPanesEstimationByWidth(maxGridWidth);
6386						
6387			if(numPanes == 1)
6388				return(maxGridWidth);
6389		}
6390		
6391		//count the size with arrows
6392		var arrowsSize = g_functions.getElementSize(g_objArrowNext);
6393		var arrowsWidth = arrowsSize.width;
6394		
6395		spaceTaken += (arrowsWidth + g_options.gridpanel_arrows_padding_hor) * 2;
6396								
6397		maxGridWidth = g_temp.panelWidth - spaceTaken;			
6398		
6399		return(maxGridWidth);
6400	}
6401		
6402	
6403	/**
6404	 * enable / disable arrows according the grid
6405	 */
6406	function setArrows(){
6407		
6408		var showArrows = false;
6409		if(g_options.gridpanel_arrows_always_on == true){
6410			showArrows = true;
6411		}
6412		else{
6413			var numPanes = g_objGrid.getNumPanes();
6414			if(numPanes > 1)
6415				showArrows = true;
6416		}
6417		
6418		if(showArrows == true){		//show arrows
6419			
6420			g_objArrowNext.show().fadeTo(0,1);
6421			g_objArrowPrev.show().fadeTo(0,1);
6422			g_temp.arrowsVisible = true;
6423			
6424		}else{		//hide arrows
6425			
6426			g_objArrowNext.hide();
6427			g_objArrowPrev.hide();
6428			g_temp.arrowsVisible = false;			
6429		
6430		}
6431		
6432	}
6433	
6434	
6435	/**
6436	 * set panel size by the given height and grid width
6437	 */
6438	function setPanelSize(){
6439		var gridSize = g_objGrid.getSize();
6440				
6441		//set panel size
6442		if(g_temp.isHorType == true)
6443			g_temp.panelHeight = gridSize.height + g_options.gridpanel_padding_border_top + g_options.gridpanel_padding_border_bottom;
6444		else
6445			g_temp.panelWidth = gridSize.width + g_options.gridpanel_padding_border_left + g_options.gridpanel_padding_border_right;
6446		
6447		g_functions.setElementSize(g_objPanel, g_temp.panelWidth, g_temp.panelHeight);
6448		
6449	}
6450	
6451	
6452	/**
6453	 * place the panel without animation
6454	 * @param panelDest
6455	 */
6456	function placePanelNoAnimation(panelDest){
6457		
6458		switch(g_temp.orientation){
6459			case "right":		//vertical
6460			case "left":
6461				g_functions.placeElement(g_objPanel, panelDest, null);
6462			break;
6463		}
6464		
6465	}
6466	
6467	
6468	
6469	function __________EVENTS___________(){};
6470	
6471	
6472	
6473	/**
6474	 * event on panel slide finish
6475	 */
6476	function onPanelSlideFinish(){
6477				
6478		g_objThis.trigger(t.events.FINISH_MOVE);
6479			
6480	}
6481	
6482	
6483	/**
6484	 * init panel events
6485	 */
6486	function initEvents(){
6487		
6488		if(g_temp.isEventsInited == true)
6489			return(false);
6490		
6491		g_temp.isEventsInited = true;
6492				
6493		if(g_objArrowPrev){
6494			g_functions.addClassOnHover(g_objArrowPrev);
6495			g_objGrid.attachPrevPaneButton(g_objArrowPrev);			
6496		}
6497		
6498		
6499		if(g_objArrowNext){
6500			g_functions.addClassOnHover(g_objArrowNext);
6501			g_objGrid.attachNextPaneButton(g_objArrowNext);			
6502		}
6503		
6504		g_panelBase.initEvents();
6505		
6506	}
6507	
6508	
6509	/**
6510	 * destroy the events
6511	 */
6512	this.destroy = function(){
6513		
6514		if(g_objArrowPrev)
6515			g_functions.destroyButton(g_objArrowPrev);
6516		
6517		if(g_objArrowNext)
6518			g_functions.destroyButton(g_objArrowNext);
6519		
6520		g_panelBase.destroy();
6521		
6522		g_objGrid.destroy();
6523	}
6524	
6525	
6526	function ______PLACE_ELEMENTS___________(){};
6527	
6528	
6529	/**
6530	 * get padding left of the grid
6531	 */
6532	function getGridPaddingLeft(){
6533		
6534		var gridPanelLeft = g_options.gridpanel_padding_border_left;
6535		
6536		return(gridPanelLeft);
6537	}
6538	
6539	
6540	/**
6541	 * place elements vertical - grid only
6542	 */
6543	function placeElements_noarrows(){
6544		
6545		//place grid
6546		var gridY = g_options.gridpanel_grid_align, gridPaddingY = 0;
6547		
6548		switch(gridY){
6549			case "top":
6550				gridPaddingY = g_options.gridpanel_padding_border_top;
6551				
6552			break;
6553			case "bottom":
6554				gridPaddingY = g_options.gridpanel_padding_border_bottom;				
6555			break;
6556		}
6557		
6558		var gridPanelLeft = getGridPaddingLeft();
6559		
6560		var gridElement = g_objGrid.getElement();		
6561		g_functions.placeElement(gridElement, gridPanelLeft, gridY, 0 , gridPaddingY);
6562				
6563	}
6564	
6565	
6566	/**
6567	 * place elements vertical - with arrows
6568	 */
6569	function placeElementsVert_arrows(){
6570		
6571		//place grid
6572		var gridY, prevArrowY, nextArrowY, nextArrowPaddingY;
6573		var objArrowSize = g_functions.getElementSize(g_objArrowPrev);		
6574		var objGridSize = g_objGrid.getSize();		
6575		
6576		
6577		switch(g_options.gridpanel_grid_align){
6578			default:
6579			case "top":
6580				gridY = g_options.gridpanel_padding_border_top + objArrowSize.height + g_options.gridpanel_arrows_padding_vert;
6581			break;
6582			case "middle":
6583				gridY = "middle";
6584			break;
6585			case "bottom":
6586				gridY = g_temp.panelHeight - objGridSize.height - objArrowSize.height - g_options.gridpanel_padding_border_bottom - g_options.gridpanel_arrows_padding_vert;
6587			break;
6588		}
6589		
6590		//place the grid
6591		var gridPanelLeft = getGridPaddingLeft();
6592		
6593		var gridElement = g_objGrid.getElement();		
6594		g_functions.placeElement(gridElement, gridPanelLeft, gridY);
6595		
6596		var objGridSize = g_objGrid.getSize();		
6597						
6598		//place arrows
6599		switch(g_options.gridpanel_arrows_align_vert){
6600			default:
6601			case "center":
6602			case "middle":
6603				prevArrowY = (objGridSize.top - objArrowSize.height) / 2;
6604				nextArrowY = objGridSize.bottom + (g_temp.panelHeight - objGridSize.bottom - objArrowSize.height) / 2;
6605				nextArrowPaddingY = 0;
6606			break;
6607			case "grid":
6608				prevArrowY = objGridSize.top - objArrowSize.height - g_options.gridpanel_arrows_padding_vert_vert
6609				nextArrowY = objGridSize.bottom + g_options.gridpanel_arrows_padding_vert;
6610				nextArrowPaddingY = 0;
6611			break;
6612			case "border":
6613			case "borders":
6614				prevArrowY = g_options.gridpanel_padding_border_top;				
6615				nextArrowY = "bottom"; 
6616				nextArrowPaddingY = g_options.gridpanel_padding_border_bottom;
6617			break;
6618		}
6619		
6620		g_functions.placeElement(g_objArrowPrev, "center", prevArrowY);
6621						
6622		g_functions.placeElement(g_objArrowNext, "center", nextArrowY, 0, nextArrowPaddingY);
6623	}
6624	
6625	
6626	/**
6627	 * place elements vertical
6628	 */
6629	function placeElementsVert(){
6630		
6631		if(g_temp.arrowsVisible == true)
6632			placeElementsVert_arrows();
6633		else
6634			placeElements_noarrows();
6635	}
6636	
6637	
6638	/**
6639	 * place elements horizontal with arrows
6640	 */
6641	function placeElementsHor_arrows(){
6642		
6643		var arrowsY, prevArrowPadding, arrowsPaddingY, nextArrowPadding;
6644		var objArrowSize = g_functions.getElementSize(g_objArrowPrev);		
6645		var objGridSize = g_objGrid.getSize();
6646		
6647		//place grid
6648		var gridY = g_options.gridpanel_padding_border_top;
6649		
6650		switch(g_options.gridpanel_grid_align){
6651			case "middle":
6652				
6653				switch(g_options.gridpanel_arrows_align_vert){
6654					default:
6655						var elementsHeight = objGridSize.height + g_options.gridpanel_arrows_padding_vert + objArrowSize.height;
6656						gridY = (g_temp.panelHeight - elementsHeight) / 2;
6657					break;
6658					case "border":
6659					case "borders":
6660						var remainHeight = g_temp.panelHeight - objArrowSize.height - g_options.gridpanel_padding_border_bottom;
6661						gridY = (remainHeight - objGridSize.height) / 2;
6662					break;
6663				}
6664								
6665			break;
6666			case "bottom":
6667				var elementsHeight = objGridSize.height + objArrowSize.height + g_options.gridpanel_arrows_padding_vert;
6668				gridY = g_temp.panelHeight - elementsHeight - g_options.gridpanel_padding_border_bottom;
6669			break;
6670		}
6671				
6672		var gridElement = g_objGrid.getElement();		
6673		var gridPanelLeft = getGridPaddingLeft();
6674		
6675		g_functions.placeElement(gridElement, gridPanelLeft, gridY);
6676		
6677		var objGridSize = g_objGrid.getSize();
6678		
6679		switch(g_options.gridpanel_arrows_align_vert){
6680			default:
6681			case "center":
6682			case "middle":
6683				arrowsY = objGridSize.bottom + (g_temp.panelHeight - objGridSize.bottom - objArrowSize.height) / 2;
6684				arrowsPaddingY = 0;								
6685			break;
6686			case "grid":
6687				arrowsY = objGridSize.bottom + g_options.gridpanel_arrows_padding_vert;
6688				arrowsPaddingY = 0;
6689			break;
6690			case "border":
6691			case "borders":
6692				arrowsY = "bottom";
6693				arrowsPaddingY = g_options.gridpanel_padding_border_bottom;
6694			break;
6695		}
6696		
6697		prevArrowPadding = -objArrowSize.width/2 - g_options.gridpanel_space_between_arrows / 2;
6698				
6699		g_functions.placeElement(g_objArrowPrev, "center", arrowsY, prevArrowPadding, arrowsPaddingY);
6700						
6701		//place next arrow
6702		var nextArrowPadding = Math.abs(prevArrowPadding);		//make positive
6703				
6704		g_functions.placeElement(g_objArrowNext, "center", arrowsY, nextArrowPadding, arrowsPaddingY);
6705					
6706	}
6707	
6708	
6709	/**
6710	 * place elements horizonatal
6711	 */
6712	function placeElementsHor(){
6713		
6714		if(g_temp.arrowsVisible == true)
6715			placeElementsHor_arrows();
6716		else
6717			placeElements_noarrows();
6718		
6719	}
6720	
6721	
6722	/**
6723	 * place elements horizontal type with arrows
6724	 */
6725	function placeElementsHorType_arrows(){
6726		
6727		//place grid
6728		var gridX, prevArrowX, nextArrowX, arrowsY;
6729		var objArrowSize = g_functions.getElementSize(g_objArrowPrev);		
6730		var objGridSize = g_objGrid.getSize();
6731		
6732		switch(g_options.gridpanel_grid_align){
6733			default:
6734			case "left":
6735				gridX = g_options.gridpanel_padding_border_left + g_options.gridpanel_arrows_padding_hor + objArrowSize.width;
6736			break;
6737			case "middle":
6738			case "center":
6739				gridX = "center";
6740			break;
6741			case "right":
6742				gridX = g_temp.panelWidth - objGridSize.width - objArrowSize.width - g_options.gridpanel_padding_border_right - g_options.gridpanel_arrows_padding_hor;
6743			break;
6744		}
6745		
6746		//place the grid		
6747		var gridElement = g_objGrid.getElement();
6748		g_functions.placeElement(gridElement, gridX, g_options.gridpanel_padding_border_top);
6749		objGridSize = g_objGrid.getSize();
6750		
6751		//place arrows, count Y
6752		switch(g_options.gridpanel_arrows_align_vert){
6753			default:
6754			case "center":
6755			case "middle":
6756				arrowsY = (objGridSize.height - objArrowSize.height) / 2 + objGridSize.top;
6757			break;
6758			case "top":
6759				arrowsY = g_options.gridpanel_padding_border_top + g_options.gridpanel_arrows_padding_vert;
6760			break;
6761			case "bottom":
6762				arrowsY = g_temp.panelHeight - g_options.gridpanel_padding_border_bottom - g_options.gridpanel_arrows_padding_vert - objArrowSize.height;
6763			break;
6764		}
6765				
6766		//get arrows X
6767		switch(g_options.gridpanel_arrows_align_hor){
6768			default:
6769			case "borders":
6770				prevArrowX = g_options.gridpanel_padding_border_left;
6771				nextArrowX = g_temp.panelWidth - g_options.gridpanel_padding_border_right - objArrowSize.width;
6772			break;
6773			case "grid":
6774				prevArrowX = objGridSize.left - g_options.gridpanel_arrows_padding_hor - objArrowSize.width;
6775				nextArrowX = objGridSize.right + g_options.gridpanel_arrows_padding_hor;
6776			break;
6777			case "center":
6778				prevArrowX = (objGridSize.left - objArrowSize.width) / 2;
6779				nextArrowX = objGridSize.right + (g_temp.panelWidth - objGridSize.right - objArrowSize.width) / 2;
6780			break;
6781		}
6782		
6783		g_functions.placeElement(g_objArrowPrev, prevArrowX, arrowsY);		
6784		g_functions.placeElement(g_objArrowNext, nextArrowX, arrowsY);
6785	}
6786	
6787	
6788	/**
6789	 * place elements horizontal type without arrows
6790	 */
6791	function placeElementHorType_noarrows(){
6792		
6793		var gridX;
6794		var objGridSize = g_objGrid.getSize();
6795		
6796		switch(g_options.gridpanel_grid_align){
6797			default:
6798			case "left":
6799				gridX = g_options.gridpanel_padding_border_left;
6800			break;
6801			case "middle":
6802			case "center":
6803				gridX = "center";
6804			break;
6805			case "right":
6806				gridX = g_temp.panelWidth - objGridSize.width - g_options.gridpanel_padding_border_right;
6807			break;
6808		}
6809		
6810		//place the grid		
6811		var gridElement = g_objGrid.getElement();
6812		g_functions.placeElement(gridElement, gridX, g_options.gridpanel_padding_border_top);
6813	}
6814	
6815	
6816	/**
6817	 * place elements when the grid in horizontal position
6818	 */
6819	function placeElementsHorType(){
6820		
6821		if(g_temp.arrowsVisible == true)
6822			placeElementsHorType_arrows();
6823		else
6824			placeElementHorType_noarrows();
6825		
6826	}
6827	
6828	
6829	/**
6830	 * place the arrows
6831	 */
6832	function placeElements(){
6833		
6834		if(g_temp.isHorType == false){
6835			
6836			if(g_options.gridpanel_vertical_scroll == true)
6837				placeElementsVert();
6838			else
6839				placeElementsHor();
6840			
6841		}else{
6842			placeElementsHorType();
6843		}
6844		
6845		g_panelBase.placeElements();
6846	}
6847	
6848	
6849	/**
6850	 * get panel orientation
6851	 */
6852	this.getOrientation = function(){
6853		
6854		return(g_temp.orientation);
6855	}
6856	
6857	
6858	/**
6859	 * set panel orientation (left, right, top, bottom)
6860	 */
6861	this.setOrientation = function(orientation){
6862		
6863		g_temp.orientation = orientation;
6864		
6865		//set isHorType temp variable for ease of use
6866		switch(orientation){
6867			case "right":
6868			case "left":
6869				g_temp.isHorType = false;
6870			break;
6871			case "top":
6872			case "bottom":
6873				g_temp.isHorType = true;
6874			break;
6875			default:
6876				throw new Error("Wrong grid panel orientation: " + orientation);
6877			break;
6878		}
6879		
6880	}
6881	
6882	/**
6883	 * set panel height
6884	 */
6885	this.setHeight = function(height){
6886		
6887		if(g_temp.isHorType == true)
6888			throw new Error("setHeight is not appliable to this orientatio ("+g_temp.orientation+"). Please use setWidth");		
6889		
6890		g_temp.panelHeight = height;
6891		var gridMaxHeight = getGridMaxHeight();
6892		
6893		g_objGrid.setMaxHeight(gridMaxHeight);
6894	}
6895	
6896	
6897	/**
6898	 * set panel width
6899	 */
6900	this.setWidth = function(width){
6901
6902		if(g_temp.isHorType == false)
6903			throw new Error("setWidth is not appliable to this orientatio ("+g_temp.orientation+"). Please use setHeight");		
6904		
6905		g_temp.panelWidth = width;
6906		
6907		var gridMaxWidth = getGridMaxWidth();
6908				
6909		g_objGrid.setMaxWidth(gridMaxWidth);
6910	}
6911	
6912	
6913	/**
6914	 * init the panel
6915	 */
6916	this.init = function(gallery, customOptions){
6917		
6918		initGridPanel(gallery, customOptions);
6919	}
6920	
6921	/**
6922	 * place panel html
6923	 */
6924	this.setHtml = function(){
6925		setHtmlPanel();
6926	}
6927	
6928	
6929	/**
6930	 * run the panel
6931	 */
6932	this.run = function(){
6933		
6934		runPanel();
6935	}
6936	
6937	
6938	/**
6939	 * get the panel element
6940	 */
6941	this.getElement = function(){
6942		return(g_objPanel);
6943	}
6944	
6945	
6946	/**
6947	 * get panel size object
6948	 */
6949	this.getSize = function(){
6950		
6951		var objSize = g_functions.getElementSize(g_objPanel);
6952		
6953		return(objSize);
6954	}
6955	
6956	this.__________Functions_From_Base_____ = function() {}
6957	
6958	/**
6959	 * tells if the panel is closed
6960	 */
6961	this.isPanelClosed = function() {		
6962		return (g_panelBase.isPanelClosed());
6963	}
6964
6965	/**
6966	 * get closed panel destanation
6967	 */
6968	this.getClosedPanelDest = function() {
6969		return g_panelBase.getClosedPanelDest();
6970	}	
6971		
6972	/**
6973	 * open the panel
6974	 */	
6975	this.openPanel = function(noAnimation) {
6976		g_panelBase.openPanel(noAnimation);
6977	}
6978	
6979	
6980	/**
6981	 * close the panel (slide in)
6982	 */
6983	this.closePanel = function(noAnimation) {
6984		g_panelBase.closePanel(noAnimation);		
6985	}	
6986	
6987	/**
6988	 * set the panel opened state
6989	 */
6990	this.setOpenedState = function(originalPos) {
6991		g_panelBase.setOpenedState(originalPos);
6992	}
6993
6994	/**
6995	 * set the panel that it's in closed state, and set original pos for opening later
6996	 */
6997	this.setClosedState = function(originalPos) {
6998		g_panelBase.setClosedState(originalPos);	
6999	}
7000	
7001	
7002	/**
7003	 * set panel disabled at start
7004	 */
7005	this.setDisabledAtStart = function(timeout){
7006		
7007		g_panelBase.setDisabledAtStart(timeout);
7008		
7009	}
7010	
7011	
7012}
7013
7014/**
7015 * thumbs class
7016 * addon to strip gallery
7017 */
7018function UGThumbsGrid(){
7019
7020	var t = this, g_objThis = jQuery(this);
7021	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objects, g_objWrapper;
7022	var g_functions = new UGFunctions(), g_arrItems, g_objGrid, g_objInner;
7023	var g_thumbs = new UGThumbsGeneral(), g_tilesDesign = new UGTileDesign();
7024	
7025	var g_options = {
7026		grid_panes_direction: "left",				//where panes will move -> left, bottom
7027		grid_num_cols: 2,							//number of grid columns
7028		grid_min_cols: 2,							//minimum number of columns (for horizontal type) - the tile size is dynamic 
7029		grid_num_rows: 2,							//number of grid rows (for horizontal type)
7030		grid_space_between_cols: 10,				//space between columns
7031		grid_space_between_rows: 10,				//space between rows
7032		grid_space_between_mobile: 10,				//space between rows and cols mobile
7033		grid_transition_duration: 300,				//transition of the panes change duration 
7034		grid_transition_easing: "easeInOutQuad",	//transition of the panes change easing function
7035		grid_carousel: false,						//next pane goes to first when last
7036		grid_padding: 0,							//set padding to the grid
7037		grid_vertical_scroll_ondrag: false			//scroll the gallery on vertical drag
7038	};
7039	
7040	this.events = {
7041		PANE_CHANGE: "pane_change"
7042	};
7043	
7044	var g_temp = {
7045			eventSizeChange: "thumb_size_change",
7046			isHorizontal: false,
7047			isMaxHeight:false,		//set if the height that set is max height. In that case need a height correction
7048			isMaxWidth:false,		//set if the height that set is max height. In that case need a height correction
7049			gridHeight: 0,
7050			gridWidth: 0,
7051			innerWidth: 0,
7052			innerHeight:0,
7053			numPanes:0,
7054			arrPanes:0,
7055			numThumbs:0,
7056			currentPane:0,
7057			numThumbsInPane:0,
7058			isNavigationVertical:false,
7059			touchActive: false,
7060			startScrollPos:0,
7061			isFirstTimeRun:true,
7062			isTilesMode: false,
7063			storedEventID: "thumbsgrid",
7064			tileMaxWidth:null,
7065			tileMaxHeight:null,
7066			spaceBetweenCols: null,
7067			spaceBetweenRows: null
7068		};
7069	
7070	
7071	function __________GENERAL_________(){};
7072	
7073	/**
7074	 * init the gallery
7075	 */
7076	function init(gallery, customOptions, isTilesMode){
7077				
7078		g_objects = gallery.getObjects();
7079		g_gallery = gallery;
7080		
7081		g_gallery.attachThumbsPanel("grid", t);
7082		
7083		g_objGallery = jQuery(gallery);
7084		g_objWrapper = g_objects.g_objWrapper;
7085		g_arrItems = g_objects.g_arrItems;
7086		
7087		if(isTilesMode === true)
7088			g_temp.isTilesMode = true;
7089		
7090		g_temp.numThumbs = g_arrItems.length;
7091		
7092		setOptions(customOptions);
7093		
7094		if(g_temp.isTilesMode == true){
7095			
7096			g_tilesDesign.setFixedMode();
7097			g_tilesDesign.setApproveClickFunction(isApproveTileClick);
7098			g_tilesDesign.init(gallery, g_options);
7099			
7100			var options_td = g_tilesDesign.getOptions();
7101			g_temp.tileMaxHeight = options_td.tile_height;
7102			g_temp.tileMaxWidth = options_td.tile_width;
7103			
7104			g_thumbs = g_tilesDesign.getObjThumbs();
7105		}else{
7106			
7107			//disable the dynamic size in thumbs
7108			customOptions.thumb_fixed_size = true;
7109			
7110			g_thumbs.init(gallery, customOptions);
7111		}
7112		
7113	}
7114	
7115	
7116	/**
7117	 * set the grid panel html
7118	 */
7119	function setHtml(parentContainer){
7120		
7121		var objParent = g_objWrapper;
7122		
7123		if(parentContainer)
7124			objParent = parentContainer;
7125		
7126		objParent.append("<div class='ug-thumbs-grid'><div class='ug-thumbs-grid-inner'></div></div>");		 
7127		g_objGrid = objParent.children(".ug-thumbs-grid");
7128		g_objInner = g_objGrid.children(".ug-thumbs-grid-inner");		
7129		
7130		//put the thumbs to inner strip
7131		
7132		if(g_temp.isTilesMode == true)
7133			g_tilesDesign.setHtml(g_objInner);
7134		else
7135			g_thumbs.setHtmlThumbs(g_objInner);
7136		
7137	}
7138	
7139	
7140	/**
7141	 * validate before running the grid
7142	 */
7143	function validateBeforeRun(){
7144		
7145		if(g_temp.isHorizontal == false){	//vertical type			
7146			if(g_temp.gridHeight == 0)
7147				throw new Error("You must set height before run.");		
7148		}else{
7149			if(g_temp.gridWidth == 0)
7150				throw new Error("You must set width before run.");					
7151		}
7152		
7153	}
7154	
7155	
7156	/**
7157	 * run the gallery after init and set html
7158	 */
7159	function run(){
7160		
7161		var selectedItem = g_gallery.getSelectedItem();
7162		
7163		validateBeforeRun();
7164		
7165		if(g_temp.isFirstTimeRun == true){
7166			
7167			initEvents();
7168						
7169			if(g_temp.isTilesMode == true){
7170				
7171				initGridDynamicSize();
7172				initSizeParams();					
7173				g_tilesDesign.run();
7174				
7175			}else{
7176				g_thumbs.setHtmlProperties();
7177				initSizeParams();			
7178				g_thumbs.loadThumbsImages();
7179			}
7180			
7181		}else{
7182			
7183			if(g_temp.isTilesMode == true){
7184				
7185				//check if dynamic size changed. If do, run the thumbs again
7186				var isChanged = initGridDynamicSize();
7187				
7188				if(isChanged == true){
7189					initSizeParams();					
7190					g_tilesDesign.run();
7191				}
7192			}
7193			
7194		}
7195				
7196		positionThumbs();
7197		
7198		if(g_temp.isFirstTimeRun == true && g_temp.isTilesMode){
7199			
7200			var objTiles = g_thumbs.getThumbs();
7201			
7202			//fire size change event
7203			objTiles.each(function(index, tile){
7204				
7205				g_objWrapper.trigger(g_temp.eventSizeChange, jQuery(tile));
7206			});
7207			
7208			objTiles.fadeTo(0,1);
7209		}
7210			
7211		if(selectedItem != null)
7212			scrollToThumb(selectedItem.index);
7213		
7214		//trigger pane change event on the start
7215		g_objThis.trigger(t.events.PANE_CHANGE, g_temp.currentPane);
7216		
7217		g_temp.isFirstTimeRun = false;
7218	}
7219	
7220	/**
7221	 * get thumb size object
7222	 */
7223	function getThumbsSize(){
7224		if(g_temp.isTilesMode == true)
7225			var objThumbSize = g_tilesDesign.getGlobalTileSize();
7226		else
7227			var objThumbSize = g_thumbs.getGlobalThumbSize();
7228		
7229		return(objThumbSize);
7230	}
7231	
7232	
7233	/**
7234	 * init grid dynamic size (tiles mode)
7235	 */
7236	function initGridDynamicSize(){
7237		
7238		if(g_temp.isTilesMode == false)
7239			throw new Error("Dynamic size can be set only in tiles mode");
7240		
7241		var isChanged = false;
7242		var isMobile = g_gallery.isMobileMode();
7243		
7244		//--- set space between cols and rows
7245		
7246		var spaceOld = g_temp.spaceBetweenCols;
7247		
7248		if(isMobile == true){
7249			g_temp.spaceBetweenCols = g_options.grid_space_between_mobile;
7250			g_temp.spaceBetweenRows = g_options.grid_space_between_mobile;
7251		}else{
7252			g_temp.spaceBetweenCols = g_options.grid_space_between_cols;
7253			g_temp.spaceBetweenRows = g_options.grid_space_between_rows;
7254		}
7255		
7256		if(g_temp.spaceBetweenCols != spaceOld)
7257			isChanged = true;
7258		
7259		//set tile size
7260		
7261		var lastThumbSize = getThumbsSize();
7262		var lastThumbWidth = lastThumbSize.width;
7263		
7264		var tileWidth = g_temp.tileMaxWidth;
7265		var numCols = g_functions.getNumItemsInSpace(g_temp.gridWidth, g_temp.tileMaxWidth, g_temp.spaceBetweenCols);
7266		
7267		if(numCols < g_options.grid_min_cols){
7268			tileWidth = g_functions.getItemSizeInSpace(g_temp.gridWidth, g_options.grid_min_cols, g_temp.spaceBetweenCols);
7269		}
7270		
7271		g_tilesDesign.setTileSizeOptions(tileWidth);
7272		
7273		if(tileWidth != lastThumbWidth)
7274			isChanged = true;
7275		
7276		
7277		return(isChanged);
7278	}
7279	
7280	
7281	/**
7282	 * init grid size horizontal
7283	 * get height param
7284	 */
7285	function initSizeParamsHor(){
7286				
7287		var objThumbSize = getThumbsSize();
7288		
7289		var thumbsHeight = objThumbSize.height;
7290		
7291		//set grid size
7292		var gridWidth = g_temp.gridWidth;
7293		var gridHeight = g_options.grid_num_rows * thumbsHeight + (g_options.grid_num_rows-1) * g_temp.spaceBetweenRows + g_options.grid_padding*2;
7294		
7295		g_temp.gridHeight = gridHeight;
7296		
7297		g_functions.setElementSize(g_objGrid, gridWidth, gridHeight);
7298	
7299		//set inner size (as grid size, will be corrected after placing thumbs
7300		g_functions.setElementSize(g_objInner, gridWidth, gridHeight);
7301		
7302		//set initial inner size params
7303		g_temp.innerWidth = gridWidth;
7304		g_temp.innerHeight = gridHeight;
7305	}
7306	
7307	
7308	/**
7309	 * init size params vertical
7310	 */
7311	function initSizeParamsVert(){
7312
7313		var objThumbSize = getThumbsSize();
7314		
7315		var thumbsWidth = objThumbSize.width;
7316		
7317		//set grid size
7318		var gridWidth = g_options.grid_num_cols * thumbsWidth + (g_options.grid_num_cols-1) * g_temp.spaceBetweenCols + g_options.grid_padding*2;
7319		var gridHeight = g_temp.gridHeight;
7320		
7321		g_temp.gridWidth = gridWidth;
7322		
7323		g_functions.setElementSize(g_objGrid, gridWidth, gridHeight);
7324	
7325		//set inner size (as grid size, will be corrected after placing thumbs
7326		g_functions.setElementSize(g_objInner, gridWidth, gridHeight);
7327		
7328		//set initial inner size params
7329		g_temp.innerWidth = gridWidth;
7330		g_temp.innerHeight = gridHeight;
7331		
7332	}
7333	
7334	/**
7335	 * init grid size
7336	 */
7337	function initSizeParams(){
7338		
7339		if(g_temp.isHorizontal == false)
7340			initSizeParamsVert();
7341		else
7342			initSizeParamsHor();
7343		
7344	}
7345
7346	
7347
7348	/**
7349	 * goto pane by index
7350	 */
7351	function scrollToThumb(thumbIndex){
7352		
7353		var paneIndex = getPaneIndexByThumbIndex(thumbIndex);
7354		if(paneIndex == -1)
7355			return(false);
7356				
7357		t.gotoPane(paneIndex, "scroll");
7358				
7359	}
7360	
7361	
7362	/**
7363	 * set the options of the strip
7364	 */
7365	function setOptions(objOptions){
7366		
7367		g_options = jQuery.extend(g_options, objOptions);
7368		
7369		g_thumbs.setOptions(objOptions);
7370		
7371		//set vertical or horizon
7372		g_temp.isNavigationVertical = (g_options.grid_panes_direction == "top" || g_options.grid_panes_direction == "bottom")
7373		
7374		g_temp.spaceBetweenCols = g_options.grid_space_between_cols;
7375		g_temp.spaceBetweenRows = g_options.grid_space_between_rows;
7376		
7377	}
7378	
7379	
7380	/**
7381	 * position the thumbs and init panes horizontally
7382	 */
7383	function positionThumb_hor(){
7384				
7385		var arrThumbs = g_objInner.children(".ug-thumb-wrapper");
7386		
7387		var posx = 0;
7388		var posy = 0;
7389		var counter = 0;
7390		var baseX = 0;
7391		var maxx = 0, maxy = 0;
7392		g_temp.innerWidth = 0;
7393		g_temp.numPanes = 1;
7394		g_temp.arrPanes = [];
7395		g_temp.numThumbsInPane = 0;
7396		
7397		//set first pane position
7398		g_temp.arrPanes.push(baseX);	
7399		
7400		var numThumbs = arrThumbs.length;
7401			
7402		for(i=0;i < numThumbs; i++){
7403			var objThumb = jQuery(arrThumbs[i]);
7404			g_functions.placeElement(objThumb, posx, posy);
7405			
7406			var thumbWidth = objThumb.outerWidth();
7407			var thumbHeight = objThumb.outerHeight();
7408			
7409			//count maxx
7410			if(posx > maxx)
7411				maxx = posx;
7412			
7413			//count maxy
7414			var endY = posy + thumbHeight;
7415			if(endY > maxy)
7416				maxy = endY;
7417			
7418			//count maxx end
7419			var endX = maxx + thumbWidth;
7420			if(endX > g_temp.innerWidth)
7421				g_temp.innerWidth = endX;
7422						
7423			posx += thumbWidth + g_temp.spaceBetweenCols;
7424			
7425			//next row
7426			counter++;
7427			if(counter >= g_options.grid_num_cols){
7428				posy += thumbHeight + g_temp.spaceBetweenRows;
7429				posx = baseX;
7430				counter = 0;
7431			}
7432			
7433			//count number thumbs in pane
7434			if(g_temp.numPanes == 1)
7435				g_temp.numThumbsInPane++;
7436			
7437			//prepare next pane
7438			if((posy + thumbHeight) > g_temp.gridHeight){
7439				posy = 0;
7440				baseX = g_temp.innerWidth + g_temp.spaceBetweenCols;
7441				posx = baseX;
7442				counter = 0;
7443								
7444				//correct max height size (do it once only)
7445				if(g_temp.isMaxHeight == true && g_temp.numPanes == 1){
7446					g_temp.gridHeight = maxy;
7447					g_objGrid.height(g_temp.gridHeight);
7448				}
7449				
7450				//save next pane props (if exists)
7451				if(i < (numThumbs - 1)){
7452					g_temp.numPanes++;
7453					
7454					//set next pane position
7455					g_temp.arrPanes.push(baseX);	
7456										
7457				}
7458			}
7459		}
7460		
7461		
7462		//set inner strip width and height
7463		g_objInner.width(g_temp.innerWidth);
7464		
7465		//set grid height
7466		if(g_temp.isMaxHeight == true && g_temp.numPanes == 1){
7467			g_temp.gridHeight = maxy;
7468			g_objGrid.height(maxy);
7469		}
7470		
7471	}
7472	
7473	
7474	/**
7475	 * position the thumbs and init panes vertically
7476	 */
7477	function positionThumb_vert(){
7478		var arrThumbs = g_objInner.children(".ug-thumb-wrapper");
7479		
7480		var posx = 0;
7481		var posy = 0;
7482		var maxy = 0;
7483		var counter = 0;
7484		var baseX = 0;
7485		var paneStartY = 0;
7486		
7487		g_temp.innerWidth = 0;
7488		g_temp.numPanes = 1;
7489		g_temp.arrPanes = [];
7490		g_temp.numThumbsInPane = 0;
7491		
7492		//set first pane position
7493		g_temp.arrPanes.push(baseX);
7494		
7495		var numThumbs = arrThumbs.length;
7496			
7497		for(i=0;i < numThumbs; i++){
7498			var objThumb = jQuery(arrThumbs[i]);
7499			g_functions.placeElement(objThumb, posx, posy);
7500			
7501			var thumbWidth = objThumb.outerWidth();
7502			var thumbHeight = objThumb.outerHeight();
7503									
7504			posx += thumbWidth + g_temp.spaceBetweenCols;
7505			
7506			var endy = (posy + thumbHeight);
7507			if(endy > maxy)
7508				maxy = endy;
7509			
7510			//next row
7511			counter++;
7512			if(counter >= g_options.grid_num_cols){
7513				posy += thumbHeight + g_temp.spaceBetweenRows;
7514				posx = baseX;
7515				counter = 0;
7516			}
7517			
7518			//count number thumbs in pane
7519			if(g_temp.numPanes == 1)
7520				g_temp.numThumbsInPane++;
7521						
7522			//prepare next pane
7523			endy = (posy + thumbHeight);
7524			var paneMaxY = paneStartY + g_temp.gridHeight;
7525			
7526			//advance next pane
7527			if(endy > paneMaxY){
7528				
7529				//correct max height size (do it once only)
7530				if(g_temp.isMaxHeight == true && g_temp.numPanes == 1){
7531					g_temp.gridHeight = maxy;
7532					g_objGrid.height(g_temp.gridHeight);
7533					paneMaxY = g_temp.gridHeight;
7534				}
7535				
7536				posy = paneMaxY + g_temp.spaceBetweenRows;					
7537				paneStartY = posy;
7538				baseX = 0;
7539				posx = baseX;
7540				counter = 0;
7541				
7542				//save next pane props (if exists)
7543				if(i < (numThumbs - 1)){
7544					g_temp.numPanes++;
7545					
7546					//set next pane position
7547					g_temp.arrPanes.push(posy);	
7548									
7549				}
7550			}
7551			
7552		}//for
7553				
7554		//set inner height 
7555		g_objInner.height(maxy);
7556		g_temp.innerHeight = maxy;
7557		
7558		//set grid height
7559		if(g_temp.isMaxHeight == true && g_temp.numPanes == 1){
7560			g_temp.gridHeight = maxy;
7561			g_objGrid.height(maxy);
7562		}
7563		
7564	}
7565
7566	
7567	/**
7568	 * position the thumbs horizontal type
7569	 */	
7570	function positionThumb_hortype(){
7571				
7572		var arrThumbs = g_objInner.children(".ug-thumb-wrapper");
7573		
7574		var baseX = g_options.grid_padding;
7575		var baseY = g_options.grid_padding;
7576		var posy = baseY;
7577		var posx = baseX;
7578		var maxx = 0, maxy = 0, paneMaxY = 0, gridMaxY = 0;
7579		var rowsCounter = 0;
7580		
7581		g_temp.innerWidth = 0;
7582		g_temp.numPanes = 1;
7583		g_temp.arrPanes = [];
7584		g_temp.numThumbsInPane = 0;
7585		
7586		//set first pane position
7587		g_temp.arrPanes.push(baseX-g_options.grid_padding);	
7588		
7589		var numThumbs = arrThumbs.length;
7590				
7591		for(i=0;i < numThumbs; i++){
7592			var objThumb = jQuery(arrThumbs[i]);
7593			
7594			var thumbWidth = objThumb.outerWidth();
7595			var thumbHeight = objThumb.outerHeight();
7596			
7597			//check end of the size, start a new row
7598			if((posx - baseX + thumbWidth) > g_temp.gridWidth){
7599				rowsCounter++;
7600				posy = 0;
7601				
7602				if(rowsCounter >= g_options.grid_num_rows){
7603					
7604					//change to a new pane					
7605					rowsCounter = 0;
7606					baseX = posx;
7607					posy = baseY;
7608					paneMaxY = 0;
7609					
7610					//change grid width to max width
7611					if(g_temp.numPanes == 1){
7612						g_temp.gridWidth = maxx+g_options.grid_padding;
7613						g_objGrid.width(g_temp.gridWidth);
7614						
7615						g_temp.gridHeight = gridMaxY + g_options.grid_padding;
7616						g_objGrid.height(g_temp.gridHeight);
7617						
7618					}
7619					
7620					g_temp.numPanes++;
7621					g_temp.arrPanes.push(baseX-g_options.grid_padding);
7622					
7623				}else{			//start new line in existing pane
7624					posx = baseX;
7625					posy = paneMaxY + g_temp.spaceBetweenRows;
7626				}
7627			}
7628			
7629			//place the thumb
7630			g_functions.placeElement(objThumb, posx, posy);
7631			
7632			//count maxx
7633			var endX = posx + thumbWidth;
7634			if(endX > maxx)
7635				maxx = endX;
7636			
7637			//count maxy
7638			var endY = posy + thumbHeight;
7639			
7640			if(endY > paneMaxY)		//pane height
7641				paneMaxY = endY;
7642			
7643			if(endY > gridMaxY)		//total height
7644				gridMaxY = endY;
7645			
7646			if(endY > maxy)
7647				maxy = endY;
7648			
7649			//count maxx end
7650			var endX = maxx + thumbWidth;
7651			if(endX > g_temp.innerWidth)
7652				g_temp.innerWidth = endX;
7653						
7654			posx += thumbWidth + g_temp.spaceBetweenCols;
7655						
7656			//count number thumbs in pane
7657			if(g_temp.numPanes == 1)
7658				g_temp.numThumbsInPane++;
7659			
7660			
7661		}//end for
7662		
7663		//set inner strip width and height
7664		g_temp.innerWidth = maxx + g_options.grid_padding;
7665		g_temp.innerHeight = gridMaxY + g_options.grid_padding;
7666		
7667		g_objInner.width(g_temp.innerWidth);
7668		g_objInner.height(g_temp.innerHeight);
7669
7670
7671		//set grid height
7672		if(g_temp.numPanes == 1){
7673			g_temp.gridWidth = maxx + g_options.grid_padding;
7674			g_temp.gridHeight = gridMaxY + g_options.grid_padding;
7675			
7676			g_objGrid.width(g_temp.gridWidth);
7677			g_objGrid.height(g_temp.gridHeight);
7678						
7679		}
7680		
7681			
7682	}
7683	
7684	
7685	/**
7686	 * position the thumbs and init panes related and width related vars
7687	 */
7688	function positionThumbs(){
7689		
7690		if(g_temp.isHorizontal == false){		//position vertical type
7691			
7692			if(g_temp.isNavigationVertical)
7693				positionThumb_vert();
7694			else
7695				positionThumb_hor();
7696			
7697		}else{
7698			positionThumb_hortype();
7699		}
7700		
7701	}
7702	
7703	
7704	/**
7705	 * validate thumb index
7706	 */
7707	function validateThumbIndex(thumbIndex){
7708		
7709		if(thumbIndex < 0 || thumbIndex >= g_temp.numThumbs){
7710			throw new Error("Thumb not exists: " + thumbIndex);
7711			return(false);
7712		}
7713		
7714		return(true);
7715	}
7716	
7717	
7718	/**
7719	 * 
7720	 * validate that the pane index exists
7721	 */
7722	function validatePaneIndex(paneIndex){
7723		
7724		if(paneIndex >= g_temp.numPanes || paneIndex < 0){
7725			throw new Error("Pane " + index + " doesn't exists.");
7726			return(false);
7727		}
7728		
7729		return(true);
7730	}
7731	
7732	/**
7733	 * validate inner position
7734	 */
7735	function validateInnerPos(pos){
7736				
7737		var absPos = Math.abs(pos);
7738		
7739		if(g_temp.isNavigationVertical == false){
7740			
7741			if(absPos < 0 || absPos >= g_temp.innerWidth){
7742				throw new Error("wrong inner x position: " + pos);
7743				return(false);
7744			}
7745			
7746		}else{
7747			
7748			if(absPos < 0 || absPos >= g_temp.innerHeight){
7749				throw new Error("wrong inner y position: " + pos);
7750				return(false);
7751			}
7752			
7753		}
7754		
7755		return(true);
7756	}
7757	
7758	
7759	
7760	
7761	/**
7762	 * 
7763	 * set inner strip position
7764	 */
7765	function setInnerPos(pos){
7766		
7767		var objCss = getInnerPosObj(pos);
7768		if(objCss == false)
7769			return(false);
7770		
7771		g_objInner.css(objCss);
7772	}
7773	
7774	
7775	/**
7776	 * animate inner to some position
7777	 */
7778	function animateInnerTo(pos){
7779		
7780		var objCss = getInnerPosObj(pos);
7781		if(objCss == false)
7782			return(false);
7783		
7784		g_objInner.stop(true).animate(objCss ,{
7785			duration: g_options.grid_transition_duration,
7786			easing: g_options.grid_transition_easing,
7787			queue: false
7788		});
7789		
7790	}
7791	
7792	/**
7793	 * animate back to current pane
7794	 */
7795	function animateToCurrentPane(){
7796		
7797		var innerPos = -g_temp.arrPanes[g_temp.currentPane];
7798		animateInnerTo(innerPos);
7799	}
7800	
7801		
7802	
7803	function __________GETTERS_________(){};
7804	
7805	/**
7806	 * get inner object size according the orientation
7807	 */
7808	function getInnerSize(){
7809		
7810		if(g_temp.isNavigationVertical == true)
7811			return(g_temp.innerHeight);
7812		else
7813			return(g_temp.innerWidth);
7814	}
7815	
7816	
7817	/**
7818	 * get pane width or height according the orientation
7819	 */
7820	function getPaneSize(){
7821		
7822		if(g_temp.isNavigationVertical == true)
7823			return(g_temp.gridHeight);
7824		else
7825			return(g_temp.gridWidth);
7826	}
7827	
7828	
7829	/**
7830	 * get object of iner position move
7831	 */
7832	function getInnerPosObj(pos){
7833				
7834		var obj = {};
7835		if(g_temp.isNavigationVertical == true)
7836			obj.top = pos + "px";
7837		else
7838			obj.left = pos + "px";
7839	
7840		return(obj);
7841	}
7842	
7843	
7844	/**
7845	 * get mouse position according the orientation
7846	 */
7847	function getMousePos(event){
7848		
7849		var mousePos = g_functions.getMousePosition(event);
7850		
7851		if(g_temp.isNavigationVertical == true)
7852			return(mousePos.pageY);
7853		else
7854			return(mousePos.pageX);
7855		
7856	}
7857	
7858	
7859	/**
7860	 * get inner position according the orientation
7861	 */
7862	function getInnerPos(){
7863		
7864		var objSize = g_functions.getElementSize(g_objInner);
7865		
7866		if(g_temp.isNavigationVertical == true)
7867			return(objSize.top);
7868		else
7869			return(objSize.left);
7870	
7871	}
7872	
7873	/**
7874	 * get pane by thumb index
7875	 */
7876	function getPaneIndexByThumbIndex(thumbIndex){
7877		
7878		//validate thumb index
7879		if(validateThumbIndex(thumbIndex) == false)
7880			return(-1);
7881		
7882		var numPane = Math.floor(thumbIndex / g_temp.numThumbsInPane);
7883		
7884		return(numPane);
7885	}
7886	
7887	/**
7888	 * get position of some pane
7889	 */
7890	function getPanePosition(index){
7891								
7892		var pos = g_temp.arrPanes[index];
7893		return(pos);
7894	}
7895	
7896	
7897	/**
7898	 * return if passed some significant movement, for thumb click
7899	 */
7900	function isSignificantPassed(){
7901		
7902		if(g_temp.numPanes == 1)
7903			return(false);
7904		
7905		var objData = g_functions.getStoredEventData(g_temp.storedEventID);
7906		
7907		var passedTime = objData.diffTime;
7908		
7909		var currentInnerPos = getInnerPos();
7910		var passedDistanceAbs = Math.abs(currentInnerPos - objData.startInnerPos);
7911		
7912		if(passedDistanceAbs > 30)
7913			return(true);
7914		
7915		if(passedDistanceAbs > 5 && passedTime > 300)
7916			return(true);
7917				
7918		return(false);
7919	}
7920	
7921	
7922	
7923	/**
7924	 * check if the movement that was held is valid for pane change
7925	 */
7926	function isMovementValidForChange(){
7927		
7928		var objData = g_functions.getStoredEventData(g_temp.storedEventID);
7929		
7930		//check position, if more then half, move
7931		var currentInnerPos = getInnerPos();
7932		diffPos = Math.abs(objData.startInnerPos - currentInnerPos);
7933				
7934		var paneSize = getPaneSize();
7935		var breakSize = Math.round(paneSize * 3 / 8);
7936		
7937		if(diffPos >= breakSize)
7938			return(true);
7939		
7940		if(objData.diffTime < 300 && diffPos > 25)
7941			return(true);
7942						
7943		return(false);
7944	}
7945	
7946	
7947	/**
7948	 * return if passed some significant movement
7949	 */
7950	function isApproveTileClick(){
7951		
7952		if(g_temp.numPanes == 1)
7953			return(true);
7954			
7955		var isApprove = g_functions.isApproveStoredEventClick(g_temp.storedEventID, g_temp.isNavigationVertical);
7956		
7957		return(isApprove);
7958	}
7959	
7960	
7961	function __________EVENTS_______(){};
7962	
7963	
7964	/**
7965	 * on thumb click event
7966	 */
7967	function onThumbClick(event){
7968		
7969		//event.preventDefault();
7970		if(isSignificantPassed() == true)
7971			return(true);
7972		
7973		//run select item operation
7974		var objThumb = jQuery(this);
7975		var objItem = g_thumbs.getItemByThumb(objThumb);
7976		
7977		g_gallery.selectItem(objItem);
7978	}
7979	
7980	
7981	/**
7982	 * on touch start
7983	 */
7984	function onTouchStart(event){
7985				
7986		if(g_temp.numPanes == 1)
7987			return(true);
7988		
7989		if(g_temp.touchActive == true)
7990			return(true);
7991		
7992		if(g_temp.isTilesMode == false)
7993			event.preventDefault();
7994		
7995		g_temp.touchActive = true;
7996		
7997		var addData = {
7998				startInnerPos: getInnerPos()
7999		};
8000		
8001		g_functions.storeEventData(event, g_temp.storedEventID, addData);
8002		
8003	}
8004	
8005	
8006	/**
8007	 * handle scroll top, return if scroll mode or not
8008	 */
8009	function handleScrollTop(){
8010		
8011		if(g_options.grid_vertical_scroll_ondrag == false)
8012			return(false);
8013		
8014		if(g_temp.isNavigationVertical == true)
8015			return(false);
8016		
8017		var scrollDir = g_functions.handleScrollTop(g_temp.storedEventID);
8018		
8019		if(scrollDir === "vert")
8020			return(true);
8021		
8022		return(false);
8023	}
8024	
8025	
8026	/**
8027	 * on touch move
8028	 */
8029	function onTouchMove(event){
8030				
8031		if(g_temp.touchActive == false)
8032			return(true);
8033		
8034		event.preventDefault();
8035		
8036		g_functions.updateStoredEventData(event, g_temp.storedEventID);
8037		
8038		var objData = g_functions.getStoredEventData(g_temp.storedEventID, g_temp.isNavigationVertical);
8039		
8040		//check if was vertical scroll
8041		var isScroll = handleScrollTop();
8042		if(isScroll)
8043			return(true);
8044		
8045		
8046		var diff = objData.diffMousePos;
8047		var innerPos = objData.startInnerPos + diff;
8048		var direction = (diff > 0) ? "prev":"next";
8049		var lastPaneSize = g_temp.arrPanes[g_temp.numPanes-1];
8050		
8051		//slow down when off limits
8052		if(g_options.grid_carousel == false && innerPos > 0 && direction == "prev"){
8053			innerPos = innerPos / 3;
8054		}
8055		
8056		//debugLine({lastSize:lastPaneSize,innerPos: innerPos});
8057		
8058		if(g_options.grid_carousel == false && innerPos < -lastPaneSize && direction == "next"){
8059			innerPos = objData.startInnerPos + diff / 3;
8060		}
8061		
8062		setInnerPos(innerPos);
8063			
8064	}
8065	
8066	
8067	/**
8068	 * on touch end
8069	 * change panes or return to current pane
8070	 */
8071	function onTouchEnd(event){
8072		
8073		if(g_temp.touchActive == false)
8074			return(true);
8075		
8076		g_functions.updateStoredEventData(event, g_temp.storedEventID);
8077		var objData = g_functions.getStoredEventData(g_temp.storedEventID, g_temp.isNavigationVertical);
8078		
8079		//event.preventDefault();
8080		g_temp.touchActive = false;
8081		
8082		if(isMovementValidForChange() == false){
8083			animateToCurrentPane();
8084			return(true);
8085		}
8086		
8087		//move pane or return back
8088		var innerPos = getInnerPos();
8089		var diff = innerPos - objData.startInnerPos;
8090		var direction = (diff > 0) ? "prev":"next";
8091		
8092		if(direction == "next"){
8093						
8094			if(g_options.grid_carousel == false && t.isLastPane())
8095				animateToCurrentPane();
8096			else
8097				t.nextPane();			
8098		}
8099		else{
8100						
8101			if(g_options.grid_carousel == false && t.isFirstPane()){
8102				animateToCurrentPane();
8103			}
8104			else
8105				t.prevPane();
8106		}
8107		
8108	}
8109	
8110	
8111	/**
8112	 * on item change
8113	 */
8114	function onItemChange(){
8115			
8116		var objItem = g_gallery.getSelectedItem();
8117		g_thumbs.setThumbSelected(objItem.objThumbWrapper);
8118		
8119		scrollToThumb(objItem.index);
8120		
8121	}
8122	
8123	
8124	/**
8125	 * init panel events
8126	 */
8127	function initEvents(){
8128		
8129		if(g_temp.isTilesMode == false){
8130			
8131			g_thumbs.initEvents();		
8132			var objThumbs = g_objGrid.find(".ug-thumb-wrapper");
8133			objThumbs.on("click touchend",onThumbClick);
8134			
8135			g_objGallery.on(g_gallery.events.ITEM_CHANGE, onItemChange);
8136			
8137		}else{
8138			g_tilesDesign.initEvents();
8139		}
8140		
8141		//touch drag events
8142		
8143		//slider mouse down - drag start
8144		g_objGrid.bind("mousedown touchstart",onTouchStart);
8145		
8146		//on body move
8147		jQuery("body").bind("mousemove touchmove",onTouchMove);
8148		
8149		//on body mouse up - drag end
8150		jQuery(window).add("body").bind("mouseup touchend", onTouchEnd);
8151		
8152	}
8153	
8154	
8155	/**
8156	 * destroy the events
8157	 */
8158	this.destroy = function(){
8159		
8160		if(g_temp.isTilesMode == false){
8161			
8162			var objThumbs = g_objGrid.find(".ug-thumb-wrapper");
8163			objThumbs.off("click");
8164			objThumbs.off("touchend");
8165			g_objGallery.on(g_gallery.events.ITEM_CHANGE);
8166			g_thumbs.destroy();		
8167						
8168		}else{
8169			g_tilesDesign.destroy();
8170		}
8171		
8172		g_objGrid.unbind("mousedown");
8173		g_objGrid.unbind("touchstart");
8174		jQuery("body").unbind("mousemove");
8175		jQuery("body").unbind("touchmove");
8176		
8177		jQuery(window).add("body").unbind("touchend");
8178		jQuery(window).add("body").unbind("mouseup");
8179		
8180		g_objThis.off(t.events.PANE_CHANGE);
8181		
8182	}
8183	
8184	
8185	
8186	this.__________EXTERNAL_GENERAL_________ = function(){};
8187	
8188	/**
8189	 * set the thumb unselected state
8190	 */
8191	this.setThumbUnselected = function(objThumbWrapper){
8192		
8193		g_thumbs.setThumbUnselected(objThumbWrapper);
8194		
8195	}
8196	
8197	/**
8198	 * check if thmb item visible, means inside the visible part of the inner strip
8199	 */
8200	this.isItemThumbVisible = function(objItem){
8201		var itemIndex = objItem.index;
8202		var paneIndex = getPaneIndexByThumbIndex(itemIndex);
8203		
8204		if(paneIndex == g_temp.currentPane)
8205			return(true);
8206		
8207		return(false);
8208	}
8209	
8210	
8211	this.__________EXTERNAL_API_________ = function(){};
8212	
8213	/**
8214	 * get estimation of number of panes by the height of the grid.
8215	 */
8216	this.getNumPanesEstimationByHeight = function(gridHeight){
8217		
8218		if(g_temp.isTilesMode == true){
8219			
8220			var thumbHeight = g_options.tile_height;
8221			
8222		}else{
8223			var thumbsOptions = g_thumbs.getOptions();		
8224			var thumbHeight = thumbsOptions.thumb_height;
8225		}
8226		
8227		var numThumbs = g_thumbs.getNumThumbs();
8228		var numRows = Math.ceil(numThumbs / g_options.grid_num_cols);
8229		
8230		var totalHeight = numRows * thumbHeight + (numRows-1) * g_temp.spaceBetweenRows;
8231			
8232		var numPanes = Math.ceil(totalHeight / gridHeight);
8233		
8234		return(numPanes);
8235	}
8236	
8237	/**
8238	 * get estimation of number of panes by the width of the grid.
8239	 */
8240	this.getNumPanesEstimationByWidth = function(gridWidth){
8241		
8242		if(g_temp.isTilesMode){
8243			var thumbWidth = g_options.tile_width;			
8244		}else{
8245			var thumbsOptions = g_thumbs.getOptions();		
8246			var thumbWidth = thumbsOptions.thumb_width;
8247		}
8248		
8249		var numThumbs = g_thumbs.getNumThumbs();
8250		var numCols = Math.ceil(numThumbs / g_options.grid_num_rows);
8251		
8252		var totalWidth = numCols * thumbWidth + (numCols-1) * g_temp.spaceBetweenCols;
8253		
8254		var numPanes = Math.ceil(totalWidth / gridWidth);
8255				
8256		return(numPanes);
8257	}
8258	
8259	
8260	/**
8261	 * get height estimation by width, works only in tiles mode
8262	 */
8263	this.getHeightEstimationByWidth = function(width){
8264		
8265		if(g_temp.isTilesMode == false)
8266			throw new Error("This function works only with tiles mode");
8267		
8268		var numThumbs = g_thumbs.getNumThumbs();
8269		var numCols = g_functions.getNumItemsInSpace(width, g_options.tile_width, g_temp.spaceBetweenCols);
8270		var numRows = Math.ceil(numThumbs / numCols);
8271		
8272		if(numRows > g_options.grid_num_rows)
8273			numRows = g_options.grid_num_rows;
8274		
8275		var gridHeight = g_functions.getSpaceByNumItems(numRows, g_options.tile_height, g_temp.spaceBetweenRows);
8276		gridHeight += g_options.grid_padding * 2;
8277		
8278		return(gridHeight);
8279	}
8280	
8281	/**
8282	 * get the grid element
8283	 */
8284	this.getElement = function(){
8285		return(g_objGrid);
8286	}
8287	
8288	/**
8289	 * get element size and position
8290	 */
8291	this.getSize = function(){
8292		
8293		var objSize = g_functions.getElementSize(g_objGrid);
8294		return(objSize);
8295		
8296	}
8297	
8298	/**
8299	 * get number of panes
8300	 */
8301	this.getNumPanes = function(){
8302		
8303		return(g_temp.numPanes);
8304	}
8305	
8306	/**
8307	 * get if the current pane is first
8308	 */
8309	this.isFirstPane = function(){
8310		
8311		if(g_temp.currentPane == 0)
8312			return(true);
8313		
8314		return(false);
8315	}
8316	
8317	
8318	/**
8319	 * get if the current pane is last
8320	 */
8321	this.isLastPane = function(){
8322		
8323		if(g_temp.currentPane == (g_temp.numPanes -1) )
8324			return(true);
8325		
8326		return(false);
8327	}
8328	
8329	
8330	/**
8331	 * get pane number, and num panes
8332	 */
8333	this.getPaneInfo = function(){
8334		
8335		var obj = {
8336			pane: g_temp.currentPane,
8337			total: g_temp.numPanes
8338		};
8339		
8340		return(obj);
8341	}
8342	
8343	
8344	/**
8345	 * get current pane
8346	 */
8347	this.getPane = function(){
8348		
8349		return(g_temp.currentPane);
8350	}
8351	
8352	
8353	/**
8354	 * set grid width (horizontal type)
8355	 */
8356	this.setWidth = function(gridWidth){
8357		g_temp.gridWidth = gridWidth;
8358		g_temp.isHorizontal = true;
8359	}
8360	
8361	/**
8362	 * set max width, the width will be corrected by the number of items
8363	 * set vertical type
8364	 */
8365	this.setMaxWidth = function(maxWidth){
8366		g_temp.gridWidth = maxWidth;
8367		g_temp.isMaxWidth = true;
8368		g_temp.isHorizontal = true;
8369	}
8370	
8371	
8372	/**
8373	 * set grid height (vertical type)
8374	 */
8375	this.setHeight = function(gridHeight){
8376		g_temp.gridHeight = gridHeight;
8377		g_temp.isHorizontal = false;
8378		
8379	}
8380	
8381	/**
8382	 * set max height, the height will be corrected by the number of items
8383	 * set the vertical type
8384	 */
8385	this.setMaxHeight = function(maxHeight){
8386		g_temp.gridHeight = maxHeight;
8387		g_temp.isMaxHeight = true;
8388		g_temp.isHorizontal = false;
8389	}
8390	
8391	
8392	/**
8393	 * goto some pane
8394	 * force skip current pane checks
8395	 */
8396	this.gotoPane = function(index, fromWhere){
8397		
8398		if(validatePaneIndex(index) == false)
8399			return(false);
8400		
8401		if(index == g_temp.currentPane)
8402			return(false);
8403		
8404		var innerPos = -g_temp.arrPanes[index];
8405		
8406		g_temp.currentPane = index;
8407		animateInnerTo(innerPos);
8408		
8409		//trigger pane change event
8410		g_objThis.trigger(t.events.PANE_CHANGE, index);
8411	}
8412	
8413	
8414	/**
8415	 * foreward to the next pane
8416	 */
8417	this.nextPane = function(){
8418				
8419		var nextPaneIndex = g_temp.currentPane+1;
8420		
8421		if(nextPaneIndex >= g_temp.numPanes){
8422			
8423			if(g_options.grid_carousel == false)
8424				return(true);
8425			
8426			nextPaneIndex = 0;
8427		}
8428		
8429		t.gotoPane(nextPaneIndex, "next");
8430	}
8431	
8432	
8433	/**
8434	 * foreward to the next pane
8435	 */
8436	this.prevPane = function(){
8437		
8438		var prevPaneIndex = g_temp.currentPane-1;
8439		if(prevPaneIndex < 0){
8440			prevPaneIndex = g_temp.numPanes-1;
8441			
8442			if(g_options.grid_carousel == false)
8443				return(false);
8444		}
8445		
8446		t.gotoPane(prevPaneIndex, "prev");
8447	}
8448	
8449	
8450	/**
8451	 * set next pane button
8452	 */
8453	this.attachNextPaneButton = function(objButton){
8454		
8455		g_functions.setButtonOnClick(objButton, t.nextPane);
8456
8457		if(g_options.grid_carousel == true)		
8458			return(true);
8459		
8460		if(t.isLastPane())
8461			objButton.addClass("ug-button-disabled");
8462		
8463		//set disabled button class if first pane
8464		g_objThis.on(t.events.PANE_CHANGE, function(){
8465			
8466			if(t.isLastPane())
8467				objButton.addClass("ug-button-disabled");
8468			else
8469				objButton.removeClass("ug-button-disabled");
8470	
8471		});
8472		
8473	}
8474	
8475	
8476	/**
8477	 * set prev pane button
8478	 */
8479	this.attachPrevPaneButton = function(objButton){
8480				
8481		g_functions.setButtonOnClick(objButton, t.prevPane);
8482		
8483		if(g_options.grid_carousel == true)		
8484			return(true);
8485		
8486		if(t.isFirstPane())
8487			objButton.addClass("ug-button-disabled");
8488		
8489		//set disabled button class if first pane
8490		g_objThis.on(t.events.PANE_CHANGE, function(){
8491			
8492			if(t.isFirstPane())
8493				objButton.addClass("ug-button-disabled");
8494			else
8495				objButton.removeClass("ug-button-disabled");
8496	
8497		});
8498		
8499	}
8500	
8501	
8502	/**
8503	 * attach bullets object
8504	 */
8505	this.attachBullets = function(objBullets){
8506		
8507		objBullets.setActive(g_temp.currentPane);
8508		
8509		jQuery(objBullets).on(objBullets.events.BULLET_CLICK, function(data, numBullet){
8510			t.gotoPane(numBullet, "theme");
8511			objBullets.setActive(numBullet);				
8512		});
8513		
8514		jQuery(t).on(t.events.PANE_CHANGE, function(data, numPane){
8515			objBullets.setActive(numPane);
8516		});
8517		
8518	}
8519	
8520	
8521	/**
8522	 * get tile design object
8523	 */
8524	this.getObjTileDesign = function(){
8525		return g_tilesDesign;
8526	}
8527	
8528	
8529	/**
8530	 * init function 
8531	 */
8532	this.init = function(gallery, customOptions, isTilesMode){
8533		
8534		init(gallery, customOptions, isTilesMode);
8535	}
8536	
8537		
8538	
8539	/**
8540	 * set html and properties
8541	 */	
8542	this.run = function(){
8543		run();
8544	}
8545
8546	
8547	/**
8548	 * set html 
8549	 */
8550	this.setHtml = function(parentContainer){
8551		
8552		setHtml(parentContainer);
8553	}
8554	
8555}
8556
8557
8558
8559/**
8560 * tiles class
8561 */
8562function UGTiles(){
8563
8564	var t = this, g_objThis = jQuery(this);
8565	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objWrapper, g_objParent;	
8566	var g_functions = new UGFunctions(), g_arrItems, g_objTileDesign = new UGTileDesign();
8567	var g_thumbs = new UGThumbsGeneral(), g_vars = {};
8568    var g_arrNestedGridRow, g_arrNestedItems;
8569	
8570	
8571	var g_options = {
8572		 tiles_type: "columns",					//columns / justified - tiles layout type
8573		 tiles_col_width: 250,					//column width - exact or base according the settings
8574		 tiles_align:"center",					//align of the tiles in the space
8575		 tiles_exact_width: false,				//exact width of column - disables the min and max columns
8576		 tiles_space_between_cols: 3,			//space between images
8577		 tiles_space_between_cols_mobile: 3,    //space between cols for mobile type
8578		 tiles_include_padding: true,			//include padding at the sides of the columns, equal to current space between cols
8579		 tiles_min_columns: 2,					//min columns
8580		 tiles_max_columns: 0,					//max columns (0 for unlimited)
8581		 tiles_keep_order: false,				//keep order - slower algorytm
8582		 tiles_set_initial_height: true,		//set some estimated height before images show
8583		 
8584		 tiles_justified_row_height: 150,		//base row height of the justified type
8585		 tiles_justified_space_between: 3,		//space between the tiles justified type
8586
8587		 tiles_nested_optimal_tile_width: 250,	// tiles optimal width
8588	     tiles_nested_col_width: null,			// nested tiles column width
8589	     tiles_nested_debug: false,
8590	     
8591		 tiles_enable_transition: true			//enable transition when screen width change
8592	};
8593	
8594	this.events = {
8595			THUMB_SIZE_CHANGE: "thumb_size_change",
8596			TILES_FIRST_PLACED: "tiles_first_placed",		//only in case of justified
8597			ALL_TILES_LOADED: "all_tiles_loaded"
8598	};
8599	
8600	var g_temp = {
8601			isFixedMode: false,   //is tiles is custom sized, not related to the images that inside
8602			isFirstTimeRun:true,   //if run once
8603			handle:null,		   //interval handle
8604			isTransActive: false,  //is transition active
8605			isTransInited: false,  //if the transition function is set
8606			isAllLoaded: false
8607	};
8608	
8609    var g_nestedWork = {
8610    		colWidth: null,
8611            nestedOptimalCols: 5,
8612            gridY: 0,
8613            maxColumns: 0,						 //maxColumns
8614            columnsValueToEnableHeightResize: 3, //columns Value To Enable Height Resize
8615            resizeLeftRightToColumn: true,
8616            currentItem: 0,
8617	        currentGap: null,
8618	        optimalTileWidth: null,
8619	        maxGridY:0
8620    }
8621	
8622	
8623	function __________GENERAL_________(){};
8624	
8625	
8626	/**
8627	 * init the gallery
8628	 */
8629	function init(gallery, customOptions){
8630		
8631		g_objects = gallery.getObjects();
8632		g_gallery = gallery;
8633		g_objGallery = jQuery(gallery);
8634		g_objWrapper = g_objects.g_objWrapper;
8635		g_arrItems = g_objects.g_arrItems;
8636		
8637		g_options = jQuery.extend(g_options, customOptions);
8638
8639		modifyOptions();
8640		
8641		g_objTileDesign.init(gallery, g_options);
8642		
8643		g_thumbs = g_objTileDesign.getObjThumbs();
8644		
8645	}
8646	
8647	
8648	/**
8649	 * modify options
8650	 */
8651	function modifyOptions(){
8652		
8653		if(g_options.tiles_min_columns < 1)
8654			g_options.tiles_min_columns = 1;
8655		
8656		//protection of max columns, can't be more then min columns
8657		if(g_options.tiles_max_columns != 0 && g_options.tiles_max_columns < g_options.tiles_min_columns){
8658			g_options.tiles_max_columns = g_options.tiles_min_columns;
8659		}
8660		
8661	}
8662	
8663	
8664	/**
8665	 * set the grid panel html
8666	 */
8667	function setHtml(objParent){
8668		
8669		if(!objParent)
8670			var objParent = g_objWrapper;
8671		
8672		g_objParent = objParent;
8673		
8674		var tilesType = g_options.tiles_type;
8675		objParent.addClass("ug-tiletype-"+tilesType);
8676		
8677		g_objTileDesign.setHtml(objParent);
8678		
8679		objParent.children(".ug-thumb-wrapper").hide();
8680	}
8681	
8682	
8683	/**
8684	 * set class that enables transition
8685	 */
8686	function setTransition(){
8687		
8688		//set the tiles in resting mode, to activate their own transitions
8689		g_objParent.addClass("ug-tiles-rest-mode");
8690		
8691		g_temp.isTransInited = true;
8692		
8693		//add css tansition
8694		if(g_options.tiles_enable_transition == true){
8695			g_objParent.addClass("ug-tiles-transit");
8696			
8697			//add image overlay transition
8698			var optionsTile = g_objTileDesign.getOptions();
8699			
8700			if(optionsTile.tile_enable_image_effect == true && optionsTile.tile_image_effect_reverse == false)
8701				g_objParent.addClass("ug-tiles-transit-overlays");
8702			
8703			g_temp.isTransActive = true;
8704		}
8705		
8706	}
8707	
8708	
8709	/**
8710	 * get parent width
8711	 */
8712	function getParentWidth(){
8713		return g_functions.getElementSize(g_objParent).width;
8714	}
8715	
8716	
8717	/**
8718	 * do some actions before transition
8719	 */
8720	function doBeforeTransition(){
8721		
8722		if(g_temp.isTransInited == false)
8723			return(false);
8724			
8725		g_objParent.addClass("ug-tiles-transition-active");
8726		g_objParent.removeClass("ug-tiles-rest-mode");
8727		
8728		//prepare for transition
8729		if(g_temp.isTransActive == false)
8730			return(false);
8731				
8732		g_objTileDesign.disableEvents();
8733	}
8734	
8735	
8736	/**
8737	 * set after transition classes
8738	 */
8739	function doAfterTransition_setClasses(){
8740		
8741		if(g_temp.isTransInited == false)
8742			return(false);
8743		
8744		g_objParent.removeClass("ug-tiles-transition-active");
8745		g_objParent.addClass("ug-tiles-rest-mode");
8746	}
8747	
8748	
8749	/**
8750	 * do some actions after transition
8751	 */
8752	function doAfterTransition(){
8753
8754		
8755		if(g_temp.isTransActive == true){
8756						
8757			//trigger size change after transition
8758			setTimeout(function(){
8759				
8760				g_objTileDesign.enableEvents();
8761				g_objTileDesign.triggerSizeChangeEventAllTiles();
8762				
8763				doAfterTransition_setClasses();
8764				
8765
8766			}, 800);
8767			
8768			//control size change 
8769			if(g_temp.handle)
8770				clearTimeout(g_temp.handle);
8771				
8772			g_temp.handle = setTimeout(function(){
8773				
8774				doAfterTransition_setClasses();
8775				
8776				g_objTileDesign.triggerSizeChangeEventAllTiles();
8777				g_temp.handle = null;
8778								
8779			}, 2000);
8780			
8781			
8782		}else{
8783						
8784			g_objTileDesign.triggerSizeChangeEventAllTiles();
8785
8786			doAfterTransition_setClasses();
8787
8788		}
8789
8790	}
8791
8792	
8793	function __________COLUMN_TYPE_RELATED_________(){};
8794	
8795	/**
8796	 * count width by number of columns
8797	 */
8798	function fillTilesVars_countWidthByCols(){
8799
8800		g_vars.colWidth = (g_vars.availWidth - g_vars.colGap * (g_vars.numCols-1)) / g_vars.numCols;
8801		g_vars.colWidth = Math.floor(g_vars.colWidth);
8802
8803		g_vars.totalWidth = g_functions.getSpaceByNumItems(g_vars.numCols, g_vars.colWidth, g_vars.colGap);
8804		
8805	}
8806	
8807	
8808	
8809	/**
8810	 * fill common tiles vars
8811	 */
8812	function fillTilesVars(){
8813
8814		g_vars.colWidth = g_options.tiles_col_width;
8815		g_vars.minCols = g_options.tiles_min_columns;
8816		g_vars.maxCols = g_options.tiles_max_columns;
8817		
8818		if(g_gallery.isMobileMode() == false){
8819			g_vars.colGap = g_options.tiles_space_between_cols;
8820		} else {
8821			g_vars.colGap = g_options.tiles_space_between_cols_mobile;
8822		}
8823		
8824		//set gallery width
8825		g_vars.galleryWidth = getParentWidth();
8826		
8827		g_vars.availWidth = g_vars.galleryWidth;
8828		
8829		if(g_options.tiles_include_padding == true)
8830			g_vars.availWidth = g_vars.galleryWidth - g_vars.colGap*2;
8831		
8832		//set the column number by exact width
8833		if(g_options.tiles_exact_width == true){
8834			
8835			g_vars.numCols = g_functions.getNumItemsInSpace(g_vars.availWidth, g_vars.colWidth, g_vars.colGap);
8836
8837			if(g_vars.maxCols > 0 && g_vars.numCols > g_vars.maxCols)
8838				g_vars.numCols = g_vars.maxCols;
8839
8840			//if less then min cols count width by cols
8841			if(g_vars.numCols < g_vars.minCols){
8842				g_vars.numCols = g_vars.minCols;
8843
8844				fillTilesVars_countWidthByCols();
8845				
8846			}else{
8847				g_vars.totalWidth = g_vars.numCols * (g_vars.colWidth + g_vars.colGap) - g_vars.colGap;
8848			}
8849			
8850		} else {
8851			
8852			//set dynamic column number
8853			
8854			var numCols = g_functions.getNumItemsInSpaceRound(g_vars.availWidth, g_vars.colWidth, g_vars.colGap);
8855						
8856			if(numCols < g_vars.minCols)
8857				numCols = g_vars.minCols;
8858			else
8859				if(g_vars.maxCols != 0 && numCols > g_vars.maxCols)
8860					numCols = g_vars.maxCols;
8861
8862			g_vars.numCols = numCols;
8863			
8864			fillTilesVars_countWidthByCols();
8865			
8866		}
8867
8868		switch(g_options.tiles_align){
8869			case "center":
8870			default:
8871				//add x to center point
8872				g_vars.addX = Math.round( (g_vars.galleryWidth - g_vars.totalWidth) / 2 );
8873			break;
8874			case "left":
8875				g_vars.addX = 0;
8876			break;
8877			case "right":
8878				g_vars.addX = g_vars.galleryWidth - g_vars.totalWidth;
8879			break;
8880		}
8881		
8882		g_vars.maxColHeight = 0;
8883		
8884		//get posx array (constact to all columns)
8885		g_vars.arrPosx = [];		
8886		for(col = 0; col < g_vars.numCols; col++){
8887			var colX = g_functions.getColX(col, g_vars.colWidth, g_vars.colGap);
8888			g_vars.arrPosx[col] = colX + g_vars.addX;
8889		}
8890		
8891		//empty heights array
8892		g_vars.colHeights = [0];
8893
8894	}
8895	
8896	
8897	
8898	
8899	
8900	/**
8901	 * get column with minimal height
8902	 */
8903	function getTilesMinCol(){
8904		var numCol = 0;
8905		
8906		var minHeight = 999999999;
8907		
8908		for(col = 0; col < g_vars.numCols; col++){
8909			
8910			if(g_vars.colHeights[col] == undefined || g_vars.colHeights[col] == 0)
8911				return col;
8912			
8913			if(g_vars.colHeights[col] < minHeight){
8914				numCol = col;
8915				minHeight = g_vars.colHeights[col];
8916			}
8917		
8918		}
8919		
8920		return(numCol);
8921	}
8922	
8923	
8924	/**
8925	 * place tile as it loads
8926	 */
8927	function placeTile(objTile, toShow, setGalleryHeight, numCol){
8928		
8929		if(numCol === null || typeof numCol == "undefined")
8930			var numCol = getTilesMinCol();
8931		
8932		//set posy
8933		var posy = 0;
8934		if(g_vars.colHeights[numCol] !== undefined)
8935			posy = g_vars.colHeights[numCol];
8936		
8937		var itemHeight = g_objTileDesign.getTileHeightByWidth(g_vars.colWidth, objTile, "placeTile");
8938		
8939		if(itemHeight === null){	//for custom html tile
8940			if(g_options.tiles_enable_transition == true)
8941				throw new Error("Can't know tile height, please turn off transition");
8942			
8943			var itemSize = g_functions.getElementSize(objTile);
8944			itemHeight = itemSize.height;
8945		}
8946		
8947		var posx = g_vars.arrPosx[numCol];
8948		
8949		g_functions.placeElement(objTile, posx, posy);
8950		
8951		var realHeight = posy + itemHeight;
8952				
8953		g_vars.colHeights[numCol] = realHeight + g_vars.colGap;
8954		
8955		//set max height
8956		if(g_vars.maxColHeight < realHeight)
8957			g_vars.maxColHeight = realHeight;
8958
8959		if(toShow == true)
8960			objTile.show().fadeTo(0,1);
8961		
8962		if(setGalleryHeight == true){
8963			g_objParent.height(g_vars.maxColHeight);			
8964		}
8965		
8966	}
8967	
8968	
8969	/**
8970	 * place the tiles
8971	 */
8972	function placeTiles(toShow){
8973		
8974		if(!toShow)
8975			toShow = false;
8976		
8977		fillTilesVars();
8978		
8979		var objThumbs = g_thumbs.getThumbs();
8980		
8981		//do some operation before the transition
8982		doBeforeTransition();
8983		
8984		//resize all thumbs
8985		g_objTileDesign.resizeAllTiles(g_vars.colWidth, g_objTileDesign.resizemode.VISIBLE_ELEMENTS);
8986		
8987		//place elements
8988		for(var index = 0; index < objThumbs.length; index++){
8989			var objTile = jQuery(objThumbs[index]);
8990			var col = undefined;
8991			if(g_options.tiles_keep_order == true)
8992				col = g_functions.getColByIndex(g_vars.numCols, index);
8993			
8994			placeTile(objTile, toShow, false, col);
8995		}
8996		
8997		//bring back the state after transition
8998		doAfterTransition();
8999		
9000		//set gallery height, according the transition
9001		var galleryHeight = g_objParent.height();
9002		
9003		if(g_temp.isTransActive == true && galleryHeight > g_vars.maxColHeight)
9004			setTimeout(function(){
9005				g_objParent.height(g_vars.maxColHeight);
9006			},700);
9007		else
9008			g_objParent.height(g_vars.maxColHeight);
9009	}
9010	
9011	
9012	/**
9013	 * check if alowed to place ordered tile
9014	 */
9015	function isOrderedTilePlaceAlowed(objTile){
9016		
9017		var index = objTile.index();
9018
9019		//don't allow double put items
9020		var currentItem = g_gallery.getItem(index);
9021		if(currentItem.ordered_placed === true)
9022			return(false);
9023
9024		
9025		var prevIndex = g_functions.getPrevRowSameColIndex(index, g_vars.numCols);
9026
9027		//put first item in the column
9028		if(prevIndex < 0)
9029			return(true);
9030				
9031		//check if previous tile in column is placed
9032		var objPrevItem = g_gallery.getItem(prevIndex);
9033		if(objPrevItem.ordered_placed === true)
9034			return(true);
9035		
9036		return(false);
9037	}
9038	
9039	
9040	/**
9041	 * place ordered tile
9042	 */
9043	function placeOrderedTile(objTile, isForce){
9044		
9045		if(isForce !== true){
9046
9047			var isAlowed = isOrderedTilePlaceAlowed(objTile);
9048			
9049			if(isAlowed == false)
9050				return(false);
9051		}
9052			
9053		var index = objTile.index();
9054				
9055		var col = g_functions.getColByIndex(g_vars.numCols, index);
9056
9057		var objItem = g_gallery.getItem(index);
9058				
9059		g_objTileDesign.resizeTile(objTile, g_vars.colWidth);
9060		
9061		placeTile(objTile, true, true, col);
9062		
9063		objItem.ordered_placed = true;
9064		
9065		//check by recursion and place next items in column
9066		var numItems = g_gallery.getNumItems();
9067		var nextIndex = g_functions.getNextRowSameColIndex(index, g_vars.numCols);
9068		if(nextIndex >= numItems)
9069			return(false);
9070		
9071		var nextTile = g_thumbs.getThumbByIndex(nextIndex);
9072		var nextItem = g_gallery.getItem(nextIndex);
9073		
9074		var isLoaded = g_thumbs.isThumbLoaded(nextTile);
9075		
9076		if(g_thumbs.isThumbLoaded(nextTile) && !nextItem.ordered_placed)
9077			placeOrderedTile(nextTile, true);
9078	}
9079	
9080	
9081	/**
9082	 * on single image load
9083	 */
9084	function onSingleImageLoad(objImage, isError){
9085		
9086		if(isError == true)
9087			return(false);
9088		
9089		objImage = jQuery(objImage);
9090		var objTile = jQuery(objImage).parent();
9091		
9092		g_thumbs.triggerImageLoadedEvent(objTile, objImage);
9093		
9094		if(g_options.tiles_keep_order == true){
9095
9096			placeOrderedTile(objTile);
9097		
9098		}else{
9099			
9100			g_objTileDesign.resizeTile(objTile, g_vars.colWidth);
9101			placeTile(objTile, true, true);
9102		}
9103	
9104	}
9105	
9106	
9107	
9108	/**
9109	 * run columns type
9110	 */
9111	function runColumnsType(){
9112		
9113		var objThumbs = g_thumbs.getThumbs();
9114		
9115		g_temp.isAllLoaded = false;
9116		
9117		fillTilesVars();
9118		
9119		var diffWidth = Math.abs(g_vars.galleryWidth - g_vars.totalWidth);
9120
9121		//set initial height of the parent by estimation
9122		if(g_options.tiles_set_initial_height == true && g_functions.isScrollbarExists() == false && diffWidth < 25){
9123			
9124			var numThumbs = objThumbs.length;
9125			var numRows = Math.ceil(objThumbs.length / g_vars.numCols);
9126			var estimateHeight = numRows * g_options.tiles_col_width * 0.75;
9127			
9128			g_objParent.height(estimateHeight);
9129			fillTilesVars();
9130		}
9131		
9132		
9133		objThumbs.fadeTo(0,0);
9134		var objImages = jQuery(g_objParent).find("img.ug-thumb-image");
9135
9136		
9137		if(g_temp.isFixedMode == true){		//fixed mode type - just place tiles before images loaded
9138			
9139			g_objThis.trigger(t.events.TILES_FIRST_PLACED);
9140			
9141			placeTiles(true);
9142			
9143			g_functions.checkImagesLoaded(objImages, function(){
9144				setTransition();
9145				g_objThis.trigger(t.events.ALL_TILES_LOADED);
9146			});
9147			
9148		}else{	//dynamic size type
9149			
9150			var initNumCols = g_vars.numCols;
9151			var initWidth = g_vars.galleryWidth;
9152			var isFirstPlace = false;
9153			
9154			//on place the tile as it loads. After all tiles loaded,check position again.
9155			g_functions.checkImagesLoaded(objImages, function(){
9156								
9157				fillTilesVars();
9158				
9159				if(initNumCols != g_vars.numCols || initWidth != g_vars.galleryWidth){
9160					placeTiles(false);
9161				}
9162				
9163				setTransition();
9164				
9165				g_objThis.trigger(t.events.ALL_TILES_LOADED);
9166				
9167			} ,function(objImage, isError){
9168				
9169				if(isFirstPlace == false)
9170					g_objThis.trigger(t.events.TILES_FIRST_PLACED);
9171				
9172				isFirstPlace = true;
9173				
9174				onSingleImageLoad(objImage, isError);
9175			
9176			});
9177			
9178		}//end dynamic mode type
9179		
9180		
9181	}
9182	
9183	
9184	function __________JUSTIFIED_TYPE_RELATED_________(){};
9185
9186	/**
9187	 * ------------ JUSTIFIED TYPE RELATED FUNCTIONS ----------------
9188	 */
9189	
9190	function getJustifiedData(){
9191		
9192		var galleryWidth = getParentWidth();
9193		
9194		var objTiles = g_thumbs.getThumbs();
9195		var rowHeightOpt = g_options.tiles_justified_row_height;
9196		var arrWidths = [];
9197		var totalWidth = 0;
9198		var gap = g_options.tiles_justified_space_between;
9199		var numTiles = objTiles.length;
9200		
9201		//get arr widths and total width
9202		jQuery.each(objTiles, function(index, objTile){
9203			objTile = jQuery(objTile);
9204			
9205			var objItem = g_thumbs.getItemByThumb(objTile);
9206			
9207			var tileWidth = objItem.thumbWidth;
9208			var tileHeight = objItem.thumbHeight;
9209			
9210			if (tileHeight !== rowHeightOpt) 
9211				tileWidth = Math.floor(objItem.thumbRatioByWidth * rowHeightOpt);
9212			
9213			arrWidths[index] = tileWidth;
9214			
9215			totalWidth += tileWidth;
9216		});
9217
9218		
9219		var numRows = Math.ceil(totalWidth / galleryWidth);
9220		
9221		if(numRows > numTiles)
9222			numRows = numTiles;
9223		
9224		var finalRowWidth = totalWidth / numRows;
9225		
9226		//fill rows array, break tiles to rows
9227		var arrRows = [], eachRowWidth = 0;
9228		var rowsWidths = [], rowsTiles = [], row = [];
9229		var progressWidth = 0, numRow = 0;
9230		
9231		jQuery.each(objTiles, function(index, objTile){
9232			var tileWidth = arrWidths[index];
9233						
9234			if( (progressWidth + tileWidth / 2) > (numRow+1) * finalRowWidth){
9235				
9236				rowsWidths[arrRows.length] = eachRowWidth;				
9237				arrRows.push(row);
9238				row = [];
9239				eachRowWidth = 0;
9240				numRow++;
9241			}
9242			
9243			progressWidth += tileWidth;
9244			eachRowWidth += tileWidth;
9245			
9246			row.push(objTile);
9247		});
9248		
9249		rowsWidths[arrRows.length] = eachRowWidth;
9250		arrRows.push(row);
9251				
9252		
9253		//set heights and position images:	
9254		var arrRowWidths = [];
9255		var arrRowHeights = [];
9256		var totalHeight = 0;
9257		
9258		jQuery.each(arrRows, function(index, row){
9259			
9260			var numTiles = row.length;
9261			var rowWidth = rowsWidths[index];
9262			
9263			var gapWidth = (row.length-1) * gap;
9264
9265			var ratio = (galleryWidth - gapWidth) / rowWidth;
9266			var rowHeight = Math.round(rowHeightOpt * ratio);
9267			
9268			//count total height
9269			totalHeight += rowHeight;
9270			if(index > 0)
9271				totalHeight += gap;
9272			
9273			arrRowHeights.push(rowHeight);
9274			
9275			//ratio between 2 heights for fixing image width:
9276            var ratioHeights = rowHeight / rowHeightOpt;
9277			
9278            //set tiles sizes:
9279            var arrRowTileWidths = [];
9280            var actualRowWidth = gapWidth;
9281            
9282            jQuery.each(row, function(indexInRow, tile){
9283            	var objTile = jQuery(tile);
9284            	var tileIndex = objTile.index();
9285            	var tileWidth = arrWidths[tileIndex];
9286            	var newWidth = Math.round(tileWidth * ratioHeights);
9287            	
9288            	arrRowTileWidths[indexInRow] = newWidth;
9289            	actualRowWidth += newWidth;            	
9290            });
9291        	
9292            //fix images widths by adding or reducing 1 pixel
9293            var diff = actualRowWidth - galleryWidth;
9294            
9295            var newTotal = 0;
9296            jQuery.each(arrRowTileWidths, function(indexInRow, width){
9297            	
9298            	if(diff == 0)            		
9299            		return(false);
9300            	
9301            	if(diff < 0){
9302            		arrRowTileWidths[indexInRow] = width + 1;
9303            		diff++;
9304            	}else{
9305            		arrRowTileWidths[indexInRow] = width - 1;
9306            		diff--;
9307            	}
9308            	
9309            	//if at last item diff stays, add all diff
9310            	if(indexInRow == (arrRowTileWidths.length-1) && diff != 0)
9311            		arrRowTileWidths[indexInRow] -= diff;
9312            });
9313            
9314            arrRowWidths[index] = arrRowTileWidths;
9315		});
9316		
9317		
9318		var objData = {
9319				arrRows: arrRows,
9320				arrRowWidths: arrRowWidths,
9321				arrRowHeights: arrRowHeights,
9322				gap: gap,
9323				totalHeight: totalHeight
9324		};
9325		
9326		return(objData);
9327	}
9328
9329	
9330	/**
9331	 * put justified images
9332	 */
9333	function placeJustified(toShow){
9334		
9335		if(!toShow)
9336			var toShow = false;
9337		
9338		var parentWidth = getParentWidth();
9339
9340		var objData = getJustifiedData();
9341		
9342		//if the width changed after height change (because of scrollbar), recalculate
9343		g_objParent.height(objData.totalHeight);
9344	
9345		var parentWidthAfter = getParentWidth();
9346		if(parentWidthAfter != parentWidth)
9347			objData = getJustifiedData();
9348		
9349		doBeforeTransition();
9350		
9351		var posy = 0;
9352		var totalWidth = 0;		//just count total widht for check / print
9353		jQuery.each(objData.arrRows, function(index, row){
9354        	
9355			var arrRowTileWidths = objData.arrRowWidths[index];
9356			var rowHeight = objData.arrRowHeights[index];
9357			
9358			//resize and place tiles
9359            var posx = 0;
9360            jQuery.each(row, function(indexInRow, tile){
9361            	            	            	
9362            	var objTile = jQuery(tile);
9363            	var tileHeight = rowHeight;
9364            	var tileWidth = arrRowTileWidths[indexInRow];
9365            	
9366            	g_objTileDesign.resizeTile(objTile, tileWidth, tileHeight, g_objTileDesign.resizemode.VISIBLE_ELEMENTS);
9367            	g_functions.placeElement(objTile, posx, posy);
9368            	
9369            	posx += tileWidth;
9370            	
9371            	if(posx > totalWidth)
9372            		totalWidth = posx;
9373            	
9374            	posx += objData.gap;
9375            	
9376            	if(toShow == true)
9377            		jQuery(tile).show();
9378            
9379            });
9380            
9381            posy += (rowHeight + objData.gap);
9382            
9383		});
9384		
9385		doAfterTransition();
9386		
9387	}
9388	
9389	
9390	
9391	/**
9392	 * run justified type gallery
9393	 */
9394	function runJustifiedType(){
9395		
9396		var objImages = jQuery(g_objWrapper).find("img.ug-thumb-image");
9397		var objTiles = g_thumbs.getThumbs();
9398
9399		g_temp.isAllLoaded = false;
9400		
9401		objTiles.fadeTo(0,0);				
9402		
9403		g_functions.checkImagesLoaded(objImages, function(){
9404			
9405			setTimeout(function(){
9406				placeJustified(true);
9407				objTiles.fadeTo(0,1);
9408				g_objThis.trigger(t.events.TILES_FIRST_PLACED);
9409				setTransition();
9410				
9411				g_objThis.trigger(t.events.ALL_TILES_LOADED);
9412				
9413			});
9414						
9415		}, function(objImage, isError){
9416
9417			objImage = jQuery(objImage);
9418			var objTile = jQuery(objImage).parent();
9419			g_thumbs.triggerImageLoadedEvent(objTile, objImage);
9420		
9421		});
9422				
9423	}
9424	
9425
9426	
9427		
9428    function __________NESTED_TYPE_RELATED_________() {    };
9429    
9430    
9431    /**
9432     * ------------ NESTED TYPE RELATED FUNCTIONS ----------------
9433     */
9434    function runNestedType() {
9435
9436        var objImages = jQuery(g_objWrapper).find("img.ug-thumb-image");
9437        var objTiles = g_thumbs.getThumbs();
9438
9439        g_temp.isAllLoaded = false;
9440        
9441        objTiles.fadeTo(0, 0);
9442
9443        g_functions.checkImagesLoaded(objImages, function () {
9444        	
9445        	if(g_gallery.isMobileMode() == true){
9446        		placeTiles(true);
9447        	}
9448        	else
9449        		placeNestedImages(true);
9450            
9451            g_objThis.trigger(t.events.TILES_FIRST_PLACED);
9452            setTransition();
9453			
9454            g_objThis.trigger(t.events.ALL_TILES_LOADED);
9455
9456        }, function (objImage, isError) {
9457
9458            objImage = jQuery(objImage);
9459            var objTile = jQuery(objImage).parent();
9460            g_thumbs.triggerImageLoadedEvent(objTile, objImage);
9461
9462        });
9463
9464    }
9465
9466    
9467    /**
9468     * fill nested vars
9469     */
9470    function fillNestedVars(){
9471
9472    	var galleryWidth = getParentWidth();
9473    	g_nestedWork.galleryWidth = galleryWidth;
9474        
9475        g_arrNestedGridRow = {};
9476    	g_nestedWork.colWidth = g_options.tiles_nested_col_width;
9477    	g_nestedWork.optimalTileWidth = g_options.tiles_nested_optimal_tile_width;
9478    	
9479    	g_nestedWork.currentGap = g_options.tiles_space_between_cols;
9480
9481    	if(g_gallery.isMobileMode() == true)
9482            g_nestedWork.currentGap = g_options.tiles_space_between_cols_mobile;
9483    	
9484        if(g_nestedWork.colWidth == null){
9485			g_nestedWork.colWidth = Math.floor(g_nestedWork.optimalTileWidth/g_nestedWork.nestedOptimalCols);
9486		} else if (g_nestedWork.optimalTileWidth > g_nestedWork.colWidth) {
9487            g_nestedWork.nestedOptimalCols = Math.ceil(g_nestedWork.optimalTileWidth / g_nestedWork.colWidth);
9488        } else {
9489            g_nestedWork.nestedOptimalCols = 1;
9490        }
9491    	
9492    	g_nestedWork.maxColumns = g_functions.getNumItemsInSpace(galleryWidth, g_nestedWork.colWidth, g_nestedWork.currentGap);
9493    	
9494        //fix col width - justify tiles
9495        g_nestedWork.colWidth = g_functions.getItemSizeInSpace(galleryWidth, g_nestedWork.maxColumns, g_nestedWork.currentGap);
9496        
9497        g_nestedWork.gridY = 0;
9498        g_arrNestedItems = []
9499        
9500        //trace(g_nestedWork);
9501        
9502    	var objTiles = g_thumbs.getThumbs();
9503		objTiles.each(function(){
9504			var objTile = jQuery(this);
9505		    var sizes = setNestedSize(objTile);
9506		    g_arrNestedItems.push(sizes);
9507		 });
9508        
9509        if (g_nestedWork.optimalTileWidth > g_nestedWork.colWidth) {
9510            g_nestedWork.nestedOptimalCols = Math.ceil(g_nestedWork.optimalTileWidth / g_nestedWork.colWidth);
9511        } else {
9512            g_nestedWork.nestedOptimalCols = 1;
9513        }
9514        
9515        g_nestedWork.totalWidth = g_nestedWork.maxColumns*(g_nestedWork.colWidth+g_nestedWork.currentGap)-g_nestedWork.currentGap;
9516
9517        switch(g_options.tiles_align){
9518			case "center":
9519			default:
9520				//add x to center point
9521				g_nestedWork.addX = Math.round( (g_nestedWork.galleryWidth - g_nestedWork.totalWidth) / 2 );
9522			break;
9523			case "left":
9524				g_nestedWork.addX = 0;
9525			break;
9526			case "right":
9527				g_nestedWork.addX = g_nestedWork.galleryWidth - g_nestedWork.totalWidth;
9528			break;
9529		}
9530        
9531        
9532        g_nestedWork.maxGridY = 0;
9533    }
9534    
9535    
9536    /**
9537     * place Nested type images
9538     */
9539    function placeNestedImages(toShow){
9540    	
9541    	var parentWidth = getParentWidth();
9542    	
9543    	fillNestedVars();
9544        placeNestedImagesCycle();
9545    	
9546        var totalHeight = g_nestedWork.maxGridY * (g_nestedWork.colWidth + g_nestedWork.currentGap) - g_nestedWork.currentGap;
9547
9548    	//if the width changed after height change (because of scrollbar), recalculate
9549		g_objParent.height(totalHeight);
9550		
9551		var parentWidthAfter = getParentWidth();
9552		
9553		if(parentWidthAfter != parentWidth){
9554    		fillNestedVars();
9555        	placeNestedImagesCycle();
9556        }
9557        
9558        if(g_options.tiles_nested_debug == false)
9559        	drawNestedImages(toShow);
9560
9561    }
9562
9563    
9564    /**
9565     * set Nested size
9566     */
9567    function setNestedSize(objTile){
9568
9569        var dimWidth, dimHeight;
9570        var output = {};
9571        
9572        var colWidth = g_nestedWork.colWidth;
9573        var gapWidth = g_nestedWork.currentGap;
9574        
9575        var objImageSize = g_objTileDesign.getTileImageSize(objTile);
9576        var index = objTile.index();
9577        
9578        var maxDim = Math.ceil(getPresettedRandomByWidth(index)*(g_nestedWork.nestedOptimalCols*1/3) + g_nestedWork.nestedOptimalCols * 2/3);
9579        
9580        var imgWidth = objImageSize.width;
9581        var imgHeight = objImageSize.height;
9582        
9583        var ratio = imgWidth/imgHeight;
9584        
9585        if(imgWidth>imgHeight){
9586            dimWidth = maxDim;
9587            dimHeight = Math.round(dimWidth/ratio);
9588            if(dimHeight == 0){
9589                dimHeight = 1;
9590            }
9591        } else {
9592            dimHeight = maxDim;
9593            dimWidth = Math.round(dimHeight*ratio);
9594            if(dimWidth == 0){
9595                dimWidth = 1;
9596            }
9597        }
9598
9599        output.dimWidth = dimWidth;
9600        output.dimHeight = dimHeight;
9601        output.width = dimWidth * colWidth + gapWidth*(dimWidth-1);
9602        output.height = dimHeight * colWidth + gapWidth*(dimHeight-1);
9603        output.imgWidth =  imgWidth;
9604        output.imgHeight = imgHeight;
9605        output.left = 0;
9606        output.top = 0;
9607        return output;
9608    }
9609
9610    
9611    /**
9612     *  get presetted random [0,1] from int
9613     */
9614    function getPresettedRandomByWidth(index){
9615        return Math.abs(Math.sin(Math.abs(Math.sin(index)*1000)));
9616    }
9617
9618    
9619    /**
9620     * place nested images debug
9621     */
9622    function placeNestedImagesDebug(toShow, placeOne){
9623        
9624    	if(placeOne == false){
9625            for(var i = g_nestedWork.currentItem; i<g_arrNestedItems.length; i++){
9626                placeNestedImage(i, true);
9627            }
9628            g_nestedWork.currentItem = g_arrNestedItems.length-1;
9629        } else {
9630            placeNestedImage(g_nestedWork.currentItem, true);
9631        }
9632        
9633    	for(var i = 0; i<=g_nestedWork.currentItem; i++){
9634            drawNestedImage(i, true);
9635        }
9636
9637        g_nestedWork.currentItem++;
9638    	
9639    }
9640    
9641    
9642    /**
9643     * start cycle of placing imgaes
9644     */
9645    function placeNestedImagesCycle(placeOne){
9646                
9647        if(g_options.tiles_nested_debug == true){
9648
9649        	if(typeof placeOne === 'undefined')
9650                placeOne = true;
9651        	
9652        	placeNestedImagesDebug(true, placeOne);
9653        	
9654        	return(false);
9655        } 
9656                
9657        for(var i = 0; i < g_arrNestedItems.length; i++)
9658                placeNestedImage(i, true);
9659    
9660    }
9661
9662
9663    /**
9664     * place Nested Image
9665     */
9666    function placeNestedImage(tileID, toShow){
9667
9668        if(!toShow)
9669            var toShow = false;
9670                
9671        g_nestedWork.maxColHeight = 0;
9672
9673        var rowsValue = g_functions.getObjectLength(g_arrNestedGridRow);
9674
9675        for(var row = g_nestedWork.gridY; row<=rowsValue+1; row++){
9676            for (var column = 0; column < g_nestedWork.maxColumns; column++) {
9677                if (isGridRowExists(g_nestedWork.gridY) == false || isGridCellTaken(g_nestedWork.gridY, column) == false) {
9678                    var totalFree = getTotalFreeFromPosition(column);
9679                    calculateOptimalStretchAndPosition(tileID, totalFree, column);
9680                                        
9681                    return;
9682                }
9683            }
9684            g_nestedWork.gridY++;
9685        }
9686        
9687    }
9688
9689    
9690    /**
9691     * calculate optimal stretch of tile
9692     */
9693    function calculateOptimalStretchAndPosition(tileID, totalFree, column){
9694
9695        var sizes = jQuery.extend(true, {}, g_arrNestedItems[tileID]);
9696        var currentWidth = sizes.dimWidth;
9697        var placeForNextImage = totalFree - sizes.dimWidth;
9698        var optimalWidth = g_nestedWork.nestedOptimalCols;
9699        var onlyCurrentImage = (totalFree<=sizes.dimWidth || placeForNextImage<=0.33*optimalWidth || totalFree<=optimalWidth);
9700
9701        //Width stretching if needed
9702        if(onlyCurrentImage){	// if free space is smaller than image width - place to this space anyway
9703            resizeToNewWidth(tileID, totalFree);
9704        } else if (placeForNextImage<=optimalWidth){ // if there are place for 2 images
9705            if(optimalWidth>=4){
9706                if(isGridImageAligned(Math.floor(totalFree/2), column) == true){
9707                    resizeToNewWidth(tileID, Math.floor(totalFree/2)+1);
9708                } else {
9709                    resizeToNewWidth(tileID, Math.floor(totalFree/2));
9710                }
9711            } else {
9712                resizeToNewWidth(objImage, totalFree);
9713            }
9714        } else {
9715            if(isGridImageAligned(currentWidth, column) == true){
9716                switch(currentWidth>=optimalWidth){
9717                    case true:
9718                        resizeToNewWidth(tileID, currentWidth-1);
9719                        break
9720                    case false:
9721                        resizeToNewWidth(tileID, currentWidth+1);
9722                        break
9723
9724                }
9725            }
9726        }
9727
9728        //Height stretching if needed
9729        sizes = jQuery.extend(true, {}, g_arrNestedItems[tileID]);
9730        var columnInfo = getGridColumnHeight(tileID, sizes.dimWidth, column); 	// [columnHeight, imagesIDs]
9731
9732        if(g_nestedWork.columnsValueToEnableHeightResize <= columnInfo[0] && g_nestedWork.maxColumns>=2*g_nestedWork.nestedOptimalCols){
9733
9734            var sideHelper = getGridImageVerticalDifference(column, sizes);
9735            var columnSizes = resizeToNewHeight(tileID, sideHelper.newHeight, true);
9736            g_arrNestedItems[tileID].dimHeight = columnSizes.dimHeight;
9737            var columnResizes = redistributeColumnItems(columnInfo, columnSizes.dimWidth, column);
9738            var columnCrosshairs = getColumnCrosshairsCount(columnResizes);
9739            var disableColumnResizes = false;
9740
9741            if(columnCrosshairs >= 2){
9742                disableColumnResizes = true;
9743            }
9744
9745            if(sideHelper.newHeight>=sizes.dimHeight){
9746                sizes = resizeToNewHeight(tileID, sideHelper.newHeight, true);
9747            }
9748            var sideResizes = getSideResizeInfo(sideHelper.idToResize, sideHelper.newHeight, sizes.dimHeight);
9749            sizes.top = g_nestedWork.gridY;
9750            sizes.left = column;
9751            sideResizes.push({"tileID": tileID, "sizes": sizes});
9752
9753            var sideResizesVal = calcResizeRatio(sideResizes);
9754            var columnResizesVal = calcResizeRatio(columnResizes);
9755
9756            if(sideResizesVal<columnResizesVal || disableColumnResizes == true) {
9757                applyResizes(sideResizes);
9758                return;
9759            } else {
9760                applyResizes(columnResizes);
9761                return;
9762            }
9763
9764
9765        }
9766        sizes.left = column;
9767        sizes.top = g_nestedWork.gridY;
9768        g_arrNestedItems[tileID] = sizes;
9769        putImageToGridRow(tileID, sizes, column, g_nestedWork.gridY);
9770        
9771        g_nestedWork.maxGridY = sizes.top + sizes.dimHeight;
9772        
9773    }
9774
9775    /**
9776     * check columns crosshairs
9777     */
9778    function getColumnCrosshairsCount(tilesAndSizes){
9779
9780        var crosshairsCountR = 0;
9781        var crosshairsCountL = 0;
9782
9783        for(var i = 0; i<tilesAndSizes.length-1; i++){
9784
9785            var sizes = tilesAndSizes[i].sizes;
9786            var topItem = -1;
9787            var bottomItem = -1;
9788            if(isGridRowExists(sizes.top+sizes.dimHeight) && g_nestedWork.maxColumns>sizes.left+sizes.dimWidth){
9789                topItem = g_arrNestedGridRow[sizes.top+sizes.dimHeight-1][sizes.left+sizes.dimWidth];
9790                bottomItem = g_arrNestedGridRow[sizes.top+sizes.dimHeight][sizes.left+sizes.dimWidth];
9791            }
9792            if(topItem != bottomItem){
9793                crosshairsCountR++;
9794            }
9795        }
9796
9797        for(var i = 0; i<tilesAndSizes.length-1; i++){
9798
9799            var sizes = tilesAndSizes[i].sizes;
9800            var topItem = -1;
9801            var bottomItem = -1;
9802            if(isGridRowExists(sizes.top+sizes.dimHeight) && sizes.left-1>=0){
9803                topItem = g_arrNestedGridRow[sizes.top+sizes.dimHeight-1][sizes.left-1];
9804                bottomItem = g_arrNestedGridRow[sizes.top+sizes.dimHeight][sizes.left-1];
9805            }
9806            if(topItem != bottomItem){
9807                crosshairsCountL++;
9808            }
9809        }
9810        return Math.max(crosshairsCountL, crosshairsCountR);
9811    }
9812
9813    /**
9814     * get size resize info
9815     */
9816    function getSideResizeInfo(idToResize, newHeight, dimHeight){
9817
9818        var currentTile = g_arrNestedItems[idToResize];
9819        var	tileHeight = currentTile.dimHeight;
9820        var tileWidth = currentTile.dimWidth;
9821        var tileLeft = currentTile.left;
9822        var tileTop = currentTile.top;
9823        var tileDimTop = parseInt(tileTop / (g_nestedWork.colWidth + g_nestedWork.currentGap));
9824        var tileDimLeft = parseInt(tileLeft / (g_nestedWork.colWidth + g_nestedWork.currentGap));
9825        var newSideHeight = tileHeight - newHeight + dimHeight;
9826
9827        var sideSizes = resizeToNewHeight(idToResize, newSideHeight, true);
9828        var output = [];
9829        output.push({"tileID": idToResize, "sizes": sideSizes});
9830        return output;
9831    }
9832
9833    /**
9834     * apply resizes to fix column
9835     */
9836    function applyResizes(resizeTilesAndSizes){
9837
9838        for(var i = 0; i<resizeTilesAndSizes.length; i++){
9839            var sizes = resizeTilesAndSizes[i].sizes;
9840            var tileID = resizeTilesAndSizes[i].tileID;
9841            g_arrNestedItems[tileID]=jQuery.extend(true, {}, sizes);
9842            putImageToGridRow(tileID, sizes, sizes.left, sizes.top);
9843        }
9844
9845    }
9846
9847    /**
9848     * redistribute heights in column
9849     * returns current item sizes
9850     */
9851    function redistributeColumnItems(columnInfo, columnWidth){
9852
9853        var originalHeight = 0;
9854        var columnHeight = 0;
9855        var objTiles = [];
9856        var cordX = 0, cordY = 0;
9857
9858        for(var i = 0; i<columnInfo[1].length; i++){
9859            var tileID = columnInfo[1][i];
9860            var currentTile = g_arrNestedItems[columnInfo[1][i]];
9861            columnHeight += currentTile.dimHeight;
9862            if(i==0){
9863                var sizes = resizeToNewWidth(tileID, columnWidth, true);
9864                originalHeight += sizes.dimHeight;
9865                objTiles.push([columnInfo[1][i], sizes.dimHeight]);
9866                continue;
9867            }
9868            originalHeight += currentTile.dimHeight;
9869            objTiles.push([tileID, currentTile.dimHeight]);
9870        }
9871
9872        cordX = currentTile.left;
9873        cordY = currentTile.top;
9874
9875        var tempHeight = columnHeight;
9876        var output = [];
9877
9878        for(var i = objTiles.length-1; i>=0; i--){
9879            var tileID = objTiles[i][0];
9880            var newHeight;
9881            if(i != 0) {
9882                newHeight = Math.max(Math.round(columnHeight*1/3),Math.floor(objTiles[i][1] * (columnHeight / originalHeight)));
9883                tempHeight = tempHeight - newHeight;
9884                sizes = resizeToNewHeight(tileID, newHeight, true);
9885                sizes.left = cordX;
9886                sizes.top = cordY;
9887                output.push({"tileID": tileID, "sizes": sizes});
9888                cordY += sizes.dimHeight;
9889            } else {
9890                newHeight = tempHeight;
9891                sizes = resizeToNewHeight(tileID, newHeight, true);
9892                sizes.left = cordX;
9893                sizes.top = cordY;
9894                output.push({"tileID": tileID, "sizes": sizes});
9895            }
9896        }
9897        return output;
9898    }
9899
9900    /**
9901     * Calculate num of objects in current column and return they are ID's
9902     */
9903    function getGridColumnHeight(tileID, dimWidth, column){
9904        var tempY = g_nestedWork.gridY-1;
9905        var curImage = 0;
9906        var prevImage = 0;
9907        var columnHeight = 1;
9908        var imagesIDs = [];
9909        var toReturn = [];
9910        imagesIDs.push(tileID);
9911        if(tempY>=0){
9912            prevImage = 0;
9913            while(tempY>=0){
9914                curImage = g_arrNestedGridRow[tempY][column];
9915                if( (typeof g_arrNestedGridRow[tempY][column-1] === 'undefined' || g_arrNestedGridRow[tempY][column-1] != g_arrNestedGridRow[tempY][column])
9916                    &&(typeof g_arrNestedGridRow[tempY][column+dimWidth] === 'undefined' || g_arrNestedGridRow[tempY][column+dimWidth-1] != g_arrNestedGridRow[tempY][column+dimWidth])
9917                    &&(g_arrNestedGridRow[tempY][column]==g_arrNestedGridRow[tempY][column+dimWidth-1])){
9918                    if(prevImage != curImage){
9919                        columnHeight++;
9920                        imagesIDs.push(curImage);
9921                    }
9922                } else {
9923                    toReturn.push(columnHeight);
9924                    toReturn.push(imagesIDs);
9925                    return toReturn;
9926                }
9927                tempY--;
9928                prevImage = curImage;
9929            }
9930            toReturn.push(columnHeight);
9931            toReturn.push(imagesIDs);
9932            return toReturn;
9933        }
9934        return [0, []];
9935    }
9936
9937    /**
9938     * get new height based on left and right difference
9939     */
9940    function getGridImageVerticalDifference(column, sizes){
9941        var newHeightR = 0;
9942        var newHeightL = 0;
9943        var dimWidth = sizes.dimWidth;
9944        var dimHeight = sizes.dimHeight;
9945        var leftID = 0;
9946        var rightID = 0;
9947        var array = jQuery.map(g_arrNestedGridRow, function(value, index) {
9948            return [value];
9949        });
9950
9951        if(typeof array[g_nestedWork.gridY] === 'undefined' || typeof array[g_nestedWork.gridY][column-1]=== 'undefined'){
9952            newHeightL = 0;
9953        } else {
9954            var tempY=0;
9955            while(true){
9956                if(typeof g_arrNestedGridRow[g_nestedWork.gridY+tempY] !== 'undefined' && g_arrNestedGridRow[g_nestedWork.gridY+tempY][column-1] != -1 ){
9957                    leftID = g_arrNestedGridRow[g_nestedWork.gridY+tempY][column-2];
9958                    tempY++;
9959                    newHeightL++;
9960                } else {
9961                    break;
9962                }
9963            }
9964        }
9965
9966        if(typeof array[g_nestedWork.gridY] === 'undefined' || typeof array[g_nestedWork.gridY][column+dimWidth]=== 'undefined'){
9967            newHeightR = 0;
9968        } else {
9969            tempY=0;
9970            while(true){
9971                if(typeof g_arrNestedGridRow[g_nestedWork.gridY+tempY] !== 'undefined' && g_arrNestedGridRow[g_nestedWork.gridY+tempY][column+dimWidth] != -1 ){
9972                    rightID = g_arrNestedGridRow[g_nestedWork.gridY+tempY][column+dimWidth+1];
9973                    tempY++;
9974                    newHeightR++;
9975                } else {
9976                    break;
9977                }
9978            }
9979        }
9980
9981        var newHeight = 0;
9982        var idToResize = 0;
9983        if(Math.abs(dimHeight - newHeightL) < Math.abs(dimHeight - newHeightR) && newHeightL != 0) {
9984            newHeight = newHeightL;
9985            idToResize = leftID;
9986        } else if (newHeightR !=0) {
9987            newHeight = newHeightR;
9988            idToResize = rightID;
9989        } else {
9990            newHeight = dimHeight; //malo li
9991        }
9992
9993        var output = {"newHeight": newHeight, "idToResize": idToResize};
9994
9995        return output;
9996    }
9997
9998    /**
9999     * resize to new Dim width
10000     */
10001    function resizeToNewWidth(tileID, newDimWidth, toReturn) {
10002        if(!toReturn){
10003            toReturn = false;
10004        }
10005        
10006        var colWidth = g_nestedWork.colWidth;
10007        var gapWidth = g_nestedWork.currentGap;
10008        var currentTile = g_arrNestedItems[tileID];
10009        var imgWidth = currentTile.imgWidth;
10010        var imgHeight = currentTile.imgHeight;
10011        var ratio = imgWidth / imgHeight;
10012        dimWidth = newDimWidth;
10013        dimHeight = Math.round(dimWidth / ratio);
10014        if(toReturn == true){
10015            var sizes = jQuery.extend(true, {}, currentTile);
10016            sizes.dimWidth = dimWidth;
10017            sizes.dimHeight = dimHeight;
10018            sizes.width = dimWidth * colWidth + gapWidth * (dimWidth - 1);
10019            sizes.height = dimHeight * colWidth + gapWidth * (dimHeight - 1);
10020            return sizes;
10021        }
10022        currentTile.dimWidth = dimWidth;
10023        currentTile.dimHeight = dimHeight;
10024        currentTile.width = dimWidth * colWidth + gapWidth * (dimWidth - 1);
10025        currentTile.height = dimHeight * colWidth + gapWidth * (dimHeight - 1);
10026    }
10027
10028    /**
10029     * resize to new height without width changing
10030     */
10031    function resizeToNewHeight(tileID, newDimHeight, toReturn) {
10032
10033        if(!toReturn){
10034            toReturn = false;
10035        }
10036
10037        var currentTile = g_arrNestedItems[tileID];
10038        var dimWidth = currentTile.dimWidth;
10039        var colWidth = g_nestedWork.colWidth;
10040        var gapWidth = g_nestedWork.currentGap;
10041
10042        if(toReturn == true){
10043            var sizes = jQuery.extend(true, {}, currentTile);
10044
10045            sizes.dimHeight = newDimHeight;
10046            sizes.width = dimWidth * colWidth + gapWidth * (dimWidth - 1);
10047            sizes.height = newDimHeight * colWidth + gapWidth * (newDimHeight - 1);
10048            
10049            return sizes;
10050        }
10051
10052        currentTile.dimHeight = newDimHeight;
10053        currentTile.width = dimWidth * colWidth + gapWidth * (dimWidth - 1);
10054        currentTile.height = newDimHeight * colWidth + gapWidth * (newDimHeight - 1);
10055    }
10056
10057    /**
10058     * calc resize koef
10059     */
10060    function calcResizeRatio(objTilesAndSizes){
10061        var tempResizes = 0;
10062        var tempNum = 0;
10063
10064        for(var i = 0; i<objTilesAndSizes.length; i++){
10065            var sizes = g_arrNestedItems[objTilesAndSizes[i].tileID];
10066            if((sizes.dimHeight != 0) && (sizes.height != 0)){
10067                resizeVal = (sizes.dimWidth/sizes.dimHeight)/(sizes.imgWidth/sizes.imgHeight);
10068            } else {
10069                return;
10070            }
10071            if(resizeVal < 1){
10072                resizeVal = 1/resizeVal;
10073            }
10074            tempResizes += resizeVal;
10075            tempNum++;
10076        }
10077        return tempResizes/tempNum;
10078    }
10079
10080    /**
10081     * check for column break
10082     */
10083    function isGridImageAligned(dimWidth, column){
10084        var y = g_nestedWork.gridY-1;
10085        if(y<=0 || isGridRowExists(y) == false){
10086            return false;
10087        }
10088        if(g_arrNestedGridRow[y][column+dimWidth-1]!=g_arrNestedGridRow[y][column+dimWidth]) {
10089            return true;
10090        }
10091
10092        return false;
10093    }
10094
10095    /**
10096     * get free line length in GridRow
10097     */
10098    function getTotalFreeFromPosition(column){
10099        var x = column;
10100        var totalFree = 0;
10101        if(isGridRowExists(g_nestedWork.gridY) == true){
10102            while(isGridCellTaken(g_nestedWork.gridY, x) == false){
10103                totalFree ++;
10104                x++;
10105            }
10106        } else {
10107            totalFree = g_nestedWork.maxColumns;
10108        }
10109        return totalFree;
10110    }
10111
10112    /**
10113     * is nestedGridRow row exists
10114     */
10115    function isGridRowExists(y){
10116        if(typeof g_arrNestedGridRow[y] === 'undefined'){
10117            return false;
10118        }
10119        return true;
10120    }
10121
10122    
10123    /**
10124     * put image to grid row
10125     */
10126    function putImageToGridRow(id, sizes, gridX, gridY){
10127        
10128    	for (var y = 0; y < sizes.dimHeight; y++) {
10129            for (var x = 0; x < sizes.dimWidth; x++) {
10130                if (isGridRowExists(gridY+y) == 0) {
10131                    addGridRow(gridY+y);
10132                }
10133                
10134                setGridCellValue(gridY+y, gridX+x, id);
10135            }
10136        }
10137    }
10138
10139    /**
10140     * add grid with Y index
10141     */
10142    function addGridRow(y){
10143        g_arrNestedGridRow[y] = new Object;
10144        for (var t = 0; t < g_nestedWork.maxColumns; t++) {
10145            g_arrNestedGridRow[y][t] = -1;
10146        }
10147    }
10148
10149    /**
10150     * isGridRowCellTaken
10151     */
10152    function isGridCellTaken(y,x){
10153        return (g_arrNestedGridRow[y][x] != -1);
10154    }
10155
10156    /**
10157     * set nestedGridRow cell value
10158     */
10159    function setGridCellValue(y,x,value){
10160        g_arrNestedGridRow[y][x]=value;
10161    }
10162
10163
10164    /**
10165     * draw nested images
10166     */
10167    function drawNestedImages(toShow){
10168    	
10169        if(!toShow)
10170            var toShow = false;
10171        
10172        doBeforeTransition();
10173        
10174        for(var i = 0; i<g_arrNestedItems.length; i++){
10175            drawNestedImage(i, toShow);
10176        }
10177
10178        g_objParent.height(g_nestedWork.maxColHeight);
10179        
10180        doAfterTransition();
10181    }
10182
10183    
10184    /**
10185     * draw nested image
10186     */
10187    function drawNestedImage(i, toShow){
10188    	
10189        var objTile = g_thumbs.getThumbByIndex(i);
10190
10191        var sizes = g_arrNestedItems[i];
10192        var newY = sizes.top * (g_nestedWork.colWidth + g_nestedWork.currentGap);
10193        var newX = g_nestedWork.addX + sizes.left * (g_nestedWork.colWidth + g_nestedWork.currentGap);
10194        
10195        g_objTileDesign.resizeTile(objTile, sizes.width, sizes.height, g_objTileDesign.resizemode.VISIBLE_ELEMENTS);
10196        
10197        g_functions.placeElement(objTile, newX, newY);
10198                
10199        if(newY + sizes.height > g_nestedWork.maxColHeight){
10200            g_nestedWork.maxColHeight = newY + sizes.height;
10201        };
10202        
10203        if(toShow == true){
10204            objTile.fadeTo(0, 1);
10205        }
10206        
10207    }
10208	
10209	
10210	function __________COMMON_AND_EVENTS_______(){};
10211	
10212	
10213	/**
10214	 * on resize event
10215	 */
10216	function onResize(){
10217		
10218		if(g_temp.isFirstTimeRun == true)
10219			return(true);
10220		
10221		if(g_temp.isAllLoaded == false)
10222			return(false);
10223		
10224		switch(g_options.tiles_type){
10225			case "columns":
10226				placeTiles(false);
10227			break;
10228			case "justified":
10229				placeJustified(false);
10230			break;
10231            case "nested":
10232            	
10233            	var isMobileMode = g_gallery.isMobileMode();
10234            	if(isMobileMode == true){
10235            		placeTiles(false);
10236            	}
10237            	else
10238            		placeNestedImages(false);
10239            
10240            break;
10241		}
10242		
10243	}
10244
10245	
10246	/**
10247	 * init panel events
10248	 */
10249	function initEvents(){
10250		
10251		//only on first placed start size change event
10252		g_objThis.on(t.events.ALL_TILES_LOADED, function(){
10253						
10254			if(g_temp.isAllLoaded == true)
10255				return(true);
10256			
10257			g_temp.isAllLoaded = true;
10258			
10259		});
10260		
10261		g_objGallery.on(g_gallery.events.SIZE_CHANGE, onResize);
10262				
10263		g_objTileDesign.initEvents();
10264				
10265	}
10266
10267	
10268	/**
10269	 * run the gallery after init and set html
10270	 */
10271	function run(){
10272				
10273		//show tiles
10274		g_objWrapper.children(".ug-tile").show();
10275
10276		if(g_temp.isFirstTimeRun == true){
10277			initEvents();
10278		}
10279		
10280		g_objTileDesign.run();
10281				
10282		switch(g_options.tiles_type){
10283			default:
10284			case "columns":
10285				runColumnsType();
10286			break;
10287			case "justified":
10288				runJustifiedType();
10289			break;
10290			case "nested":
10291				runNestedType();
10292			break;
10293		}
10294		
10295		
10296		g_temp.isFirstTimeRun = false;
10297	}
10298	
10299	
10300	/**
10301	 * destroy the events
10302	 */
10303	this.destroy = function(){
10304		
10305		g_objGallery.off(g_gallery.events.SIZE_CHANGE);
10306		g_objTileDesign.destroy();
10307	}
10308	
10309	/**
10310	 * set the custom size mode.
10311	 * set it before the init
10312	 */
10313	this.setFixedSizeMode = function(){
10314		g_temp.isFixedMode = true;
10315		g_objTileDesign.setFixedMode();
10316	}
10317	
10318	
10319	/**
10320	 * init function for avia controls
10321	 */
10322	this.init = function(gallery, customOptions){
10323		
10324		init(gallery, customOptions);
10325	}
10326
10327	
10328	/**
10329	 * set html
10330	 */
10331	this.setHtml = function(objParent){
10332		setHtml(objParent);
10333	}
10334	
10335	/**
10336	 * get tile design object
10337	 */
10338	this.getObjTileDesign = function(){
10339		return(g_objTileDesign);
10340	}
10341	
10342	/**
10343	 * set html and properties
10344	 */	
10345	this.run = function(){
10346		run();
10347	}
10348	
10349	
10350}
10351
10352
10353
10354/**
10355 * tiles design class
10356 */
10357function UGTileDesign(){
10358	
10359	var t = this, g_objThis = jQuery(this);	
10360	var g_gallery = new UniteGalleryMain(), g_objGallery;
10361	var g_functions = new UGFunctions(), g_objParentWrapper, g_objWrapper;
10362	var g_thumbs = new UGThumbsGeneral(), g_items;
10363	
10364	this.resizemode = {			//modes constants for resize tile
10365		FULL: "full",
10366		WRAPPER_ONLY: "wrapper_only",
10367		VISIBLE_ELEMENTS: "visible_elements"
10368	};
10369	
10370	this.sizeby = {				//sizeby option constants
10371		GLOBAL_RATIO: "global_ratio",
10372		TILE_RATIO: "tile_ratio",
10373		IMAGE_RATIO: "image_ratio",
10374		CUSTOM: "custom"
10375	};
10376	
10377	this.events = {
10378			TILE_CLICK: "tile_click"
10379	};
10380	
10381	var g_options = {
10382						
10383			tile_width: 250,						//in case of fixed size: tile width
10384			tile_height: 200,						//in case of fixed size: tile height
10385			tile_size_by:t.sizeby.IMAGE_RATIO,		//image ratio, tile ratio , global_ratio - decide by what parameter resize the tile
10386			tile_visible_before_image:false,		//tile visible before image load
10387			
10388			tile_enable_background:true,			//enable backgruond of the tile
10389			tile_background_color: "#F0F0F0",		//tile background color
10390			
10391			tile_enable_border:false,				//enable border of the tile
10392			tile_border_width:3,					//tile border width
10393			tile_border_color:"#F0F0F0",			//tile border color
10394			tile_border_radius:0,					//tile border radius (applied to border only, not to outline)
10395			
10396			tile_enable_outline: false,				//enable outline of the tile (works only together with the border)
10397			tile_outline_color: "#8B8B8B",			//tile outline color
10398			
10399			tile_enable_shadow:false,				//enable shadow of the tile
10400			tile_shadow_h:1,						//position of horizontal shadow
10401			tile_shadow_v:1,						//position of vertical shadow
10402			tile_shadow_blur:3,						//shadow blur
10403			tile_shadow_spread:2,					//shadow spread
10404			tile_shadow_color:"#8B8B8B",			//shadow color
10405			
10406			tile_enable_action:	true,				//enable tile action on click like lightbox
10407			tile_as_link: false,					//act the tile as link, no lightbox will appear
10408			tile_link_newpage: true,				//open the tile link in new page
10409
10410			tile_enable_overlay: true,				//enable tile color overlay (on mouseover)
10411			tile_overlay_opacity: 0.4,				//tile overlay opacity
10412			tile_overlay_color: "#000000",			//tile overlay color
10413			
10414			tile_enable_icons: true,				//enable icons in mouseover mode
10415			tile_show_link_icon: false,				//show link icon (if the tile has a link). In case of tile_as_link this option not enabled
10416			tile_videoplay_icon_always_on: 'never',	//'always', 'never', 'mobile_only', 'desktop_only' always show video play icon
10417			tile_space_between_icons: 26,			//initial space between icons, (on small tiles it may change)
10418			
10419			tile_enable_image_effect:false,			//enable tile image effect
10420			tile_image_effect_type: "bw",			//bw, blur, sepia - tile effect type
10421			tile_image_effect_reverse: false,		//reverce the image, set only on mouseover state
10422			
10423			tile_enable_textpanel: false,			 //enable textpanel
10424			tile_textpanel_source: "title",			 //title,desc,desc_title,title_and_desc. source of the textpanel. desc_title - if description empty, put title
10425			tile_textpanel_always_on: false,		 //textpanel always visible - for inside type
10426			tile_textpanel_appear_type: "slide",	 //slide, fade - appear type of the textpanel on mouseover
10427			tile_textpanel_position:"inside_bottom", //inside_bottom, inside_top, inside_center, top, bottom the position of the textpanel
10428			tile_textpanel_offset:0					 //vertical offset of the textpanel
10429	};
10430	
10431	
10432	var g_defaults = {
10433			thumb_color_overlay_effect: true,
10434			thumb_overlay_reverse: true,
10435			thumb_image_overlay_effect: false,
10436			tile_textpanel_enable_description: false,
10437			tile_textpanel_bg_opacity: 0.6,
10438			tile_textpanel_padding_top:8,
10439			tile_textpanel_padding_bottom: 8
10440	};
10441	
10442	var g_temp = {
10443		ratioByHeight:0,
10444		ratioByWidth:0,
10445		eventSizeChange: "thumb_size_change",
10446		funcCustomTileHtml: null,
10447		funcCustomPositionElements: null,
10448		funcParentApproveClick: null,
10449		isSaparateIcons: false,
10450		tileInnerReduce: 0,		//how much reduce from the tile inner elements from border mostly
10451		isTextpanelOutside: false,	//is the textpanel is out of tile image border
10452		hasImageContainer:false,
10453		isVideoplayIconAlwaysOn:false,
10454		isTextPanelHidden:false
10455	};
10456	
10457	
10458	/**
10459	 * init the tile object
10460	 */
10461	function init(gallery, customOptions){
10462		
10463		g_gallery = gallery;
10464		
10465		g_objGallery = jQuery(gallery);		
10466		
10467		var objects = g_gallery.getObjects();
10468		g_objWrapper = objects.g_objWrapper;
10469		
10470		g_items = g_gallery.getArrItems();
10471				
10472		g_options = jQuery.extend(g_options, g_defaults);
10473		
10474		g_options = jQuery.extend(g_options, customOptions);
10475				
10476		modifyOptions();
10477				
10478		g_thumbs.init(gallery, g_options);	
10479		
10480		var objCustomOptions = {allow_onresize:false};
10481		
10482		var customThumbsAdd = ["overlay"];
10483		
10484		if(g_temp.funcCustomTileHtml)
10485			customThumbsAdd = [];
10486		
10487		g_thumbs.setCustomThumbs(setHtmlThumb, customThumbsAdd, objCustomOptions);
10488		
10489		//get thumb default options too:
10490		var thumbOptions = g_thumbs.getOptions();
10491		g_options = jQuery.extend(g_options, thumbOptions);
10492		
10493		//set ratios of fixed mode
10494		g_temp.ratioByWidth = g_options.tile_width / g_options.tile_height;
10495		g_temp.ratioByHeight = g_options.tile_height / g_options.tile_width;
10496		
10497		
10498		//set if tile has image container
10499		if(g_options.tile_size_by == t.sizeby.GLOBAL_RATIO && g_temp.isTextpanelOutside)
10500			g_temp.hasImageContainer = true;
10501		
10502	}
10503	
10504	
10505	/**
10506	 * set thumb and textpanel options according tile options
10507	 */
10508	function modifyOptions(){
10509
10510		//set overlay related options
10511		if(g_options.tile_enable_overlay == true){
10512			
10513			g_options.thumb_overlay_opacity = g_options.tile_overlay_opacity;
10514			g_options.thumb_overlay_color = g_options.tile_overlay_color;
10515		
10516		}else if(g_options.tile_enable_icons == false){		//if nothing on overlay - turn it off
10517			g_options.thumb_color_overlay_effect = false;		
10518		}else{											//if icons enabled - make it transparent
10519			g_options.thumb_overlay_opacity = 0;
10520		}
10521		
10522		//set item as link
10523		if(g_options.tile_as_link){
10524			g_options.thumb_wrapper_as_link = true;
10525			g_options.thumb_link_newpage = g_options.tile_link_newpage;
10526		}
10527		
10528		//outline cannot appear without border
10529		if(g_options.tile_enable_outline == true && g_options.tile_enable_border == false)
10530			g_options.tile_enable_outline = false;
10531		
10532		//set inner reduce value - in case of the border
10533		g_temp.tileInnerReduce = 0;
10534		if(g_options.tile_enable_border){
10535			g_temp.tileInnerReduce = g_options.tile_border_width * 2;
10536			g_thumbs.setThumbInnerReduce(g_temp.tileInnerReduce);
10537		}
10538
10539		//check if saparate icons
10540		g_temp.isSaparateIcons = !g_functions.isRgbaSupported();
10541		
10542		//set if the textpanel is enabled and outside
10543		if(g_options.tile_enable_textpanel == true){
10544			
10545			//optimize for touch device
10546			switch(g_options.tile_textpanel_position){
10547				case "top":
10548					g_options.tile_textpanel_align = "top";
10549				case "bottom":
10550					g_temp.isTextpanelOutside = true;
10551					g_options.tile_textpanel_always_on = true;
10552					g_options.tile_textpanel_offset = 0;
10553				break;
10554				case "inside_top":
10555					g_options.tile_textpanel_align = "top";
10556				break;
10557				case "middle":
10558					g_options.tile_textpanel_align = "middle";
10559					g_options.tile_textpanel_appear_type = "fade";
10560				break;
10561			}
10562			
10563			//if text panel oppearing with the overlay, icons should be saparated
10564			if(g_options.tile_textpanel_always_on == false)
10565				g_temp.isSaparateIcons = true;
10566			
10567		}
10568		
10569		
10570		//if the textpanel offset is not from the border, it's always fade.
10571		if(g_options.tile_textpanel_offset != 0){
10572			g_options.tile_textpanel_appear_type = "fade";
10573			g_options.tile_textpanel_margin = g_options.tile_textpanel_offset;
10574		}
10575		
10576		//enable description if needed
10577		if(g_options.tile_textpanel_source == "title_and_desc"){
10578			g_options.tile_textpanel_enable_description = true;
10579			g_options.tile_textpanel_desc_style_as_title = true;
10580		}
10581		
10582	}
10583	
10584
10585	/**
10586	 * set options before render
10587	 */
10588	function modifyOptionsBeforeRender(){
10589		
10590		var isMobile = g_gallery.isMobileMode();
10591		
10592		//set text panel show / hide
10593		
10594		g_temp.isTextPanelHidden = false;
10595		if(isMobile == true && g_options.tile_textpanel_always_on == false)
10596			g_temp.isTextPanelHidden = true;
10597		
10598		
10599		//set video icon always on true / false
10600		
10601		g_temp.isVideoplayIconAlwaysOn = g_options.tile_videoplay_icon_always_on;
10602		
10603		switch(g_options.tile_videoplay_icon_always_on){
10604			case "always":
10605				g_temp.isVideoplayIconAlwaysOn = true;
10606			break;
10607			case "never":
10608				g_temp.isVideoplayIconAlwaysOn = false;
10609			break;
10610			case "mobile_only":
10611				g_temp.isVideoplayIconAlwaysOn = (isMobile == true)?true:false;
10612			break;
10613			case "desktop_only":
10614				g_temp.isVideoplayIconAlwaysOn = (isMobile == false)?true:false;
10615			break;
10616		}
10617		
10618		
10619	}
10620
10621	
10622	/**
10623	 * set thumb html
10624	 */
10625	function setHtmlThumb(objThumbWrapper, objItem){
10626		
10627		objThumbWrapper.addClass("ug-tile");
10628		
10629		if(g_temp.funcCustomTileHtml){
10630			g_temp.funcCustomTileHtml(objThumbWrapper, objItem);
10631			return(false);
10632		}
10633		
10634		var html = "";
10635			
10636		//add image container
10637		if(g_temp.hasImageContainer == true){
10638			html += "<div class='ug-image-container ug-trans-enabled'>";
10639		}
10640		
10641		//add thumb image:
10642		var classImage = "ug-thumb-image";
10643
10644		if(g_options.tile_enable_image_effect == false || g_options.tile_image_effect_reverse == true)
10645			classImage += " ug-trans-enabled";
10646		
10647		var imageAlt = g_functions.stripTags(objItem.title);
10648		imageAlt = g_functions.htmlentitles(imageAlt);
10649		
10650		html += "<img src=\""+g_functions.escapeDoubleSlash(objItem.urlThumb)+"\" alt='"+imageAlt+"' class='"+classImage+"'>";
10651
10652		if(g_temp.hasImageContainer == true){
10653			html += "</div>";
10654		}	
10655		
10656		objThumbWrapper.append(html);
10657		
10658		
10659		if(g_options.tile_size_by == t.sizeby.GLOBAL_RATIO){
10660			objThumbWrapper.fadeTo(0,0);		//turn on in thumbsGeneral
10661		}
10662		
10663		//---- set thumb styles ---- 
10664		
10665		//set border:
10666		var objCss = {};
10667		
10668		if(g_options.tile_enable_background == true){
10669			objCss["background-color"] = g_options.tile_background_color;
10670		}
10671		
10672		if(g_options.tile_enable_border == true){
10673			objCss["border-width"] = g_options.tile_border_width+"px";
10674			objCss["border-style"] = "solid";
10675			objCss["border-color"] = g_options.tile_border_color;
10676			
10677			if(g_options.tile_border_radius)
10678				objCss["border-radius"] = g_options.tile_border_radius+"px";
10679		}
10680		
10681		//set outline:
10682		if(g_options.tile_enable_outline == true){
10683			objCss["outline"] = "1px solid " + g_options.tile_outline_color;
10684		}
10685		
10686		//set shadow
10687		if(g_options.tile_enable_shadow == true){
10688			var htmlShadow = g_options.tile_shadow_h+"px ";
10689			htmlShadow += g_options.tile_shadow_v+"px ";
10690			htmlShadow += g_options.tile_shadow_blur+"px ";
10691			htmlShadow += g_options.tile_shadow_spread+"px ";
10692			htmlShadow += g_options.tile_shadow_color;
10693			
10694			objCss["box-shadow"] = htmlShadow;
10695		}
10696		
10697		objThumbWrapper.css(objCss);
10698		
10699		
10700		//----- add icons
10701		
10702		var htmlAdd = "";
10703		
10704		if(g_options.tile_enable_icons){
10705			
10706			//add zoom icon
10707			if(g_options.tile_as_link == false && g_options.tile_enable_action == true){
10708				var iconPlayClass = "ug-button-play ug-icon-zoom";
10709				if(objItem.type != "image")
10710					iconPlayClass = "ug-button-play ug-icon-play";
10711				
10712				htmlAdd += "<div class='ug-tile-icon " + iconPlayClass + "' style='display:none'></div>";
10713			}
10714			
10715			//add link icon
10716			if(objItem.link && g_options.tile_show_link_icon == true || g_options.tile_as_link == true){
10717				
10718				if(g_options.tile_as_link == false){
10719					var linkTarget = "";
10720					if(g_options.tile_link_newpage == true)
10721						linkTarget = " target='_blank'";
10722					
10723					htmlAdd += "<a href='"+objItem.link+"'"+linkTarget+" class='ug-tile-icon ug-icon-link'></a>";					
10724				}else{
10725					htmlAdd += "<div class='ug-tile-icon ug-icon-link' style='display:none'></div>";					
10726				}
10727				
10728			}
10729		
10730		var toSaparateIcon = g_temp.isSaparateIcons;
10731		if(toSaparateIcon == false && objItem.type != "image" && g_temp.isVideoplayIconAlwaysOn == true)
10732			toSaparateIcon = true;
10733		
10734		if(toSaparateIcon)		//put the icons on the thumb
10735			var objOverlay = objThumbWrapper;
10736		else
10737			var objOverlay = objThumbWrapper.children(".ug-thumb-overlay");
10738		
10739		objOverlay.append(htmlAdd);		
10740		
10741		var objButtonZoom = objOverlay.children("." + iconPlayClass);
10742		
10743		if(objButtonZoom.length == 0)
10744			objButtonZoom = null;
10745		else
10746			objButtonZoom.hide();
10747		
10748		var objButtonLink = objOverlay.children(".ug-icon-link");
10749		
10750		if(objButtonLink.length == 0)
10751			objButtonLink = null;
10752		else
10753			objButtonLink.hide();
10754		
10755		//if only zoom icon, make the tile clickable for lightbox open
10756		if(!objButtonLink && g_options.tile_enable_action == true)
10757			objThumbWrapper.addClass("ug-tile-clickable");
10758		
10759		}  //if icons enabled
10760		else{		//if the icons don't enabled, set the tile clickable
10761			
10762			if(g_options.tile_enable_action == true)
10763				objThumbWrapper.addClass("ug-tile-clickable");
10764		
10765		}
10766		
10767		//add image overlay
10768		if(g_options.tile_enable_image_effect == true){
10769			
10770			var imageEffectClassAdd = "";
10771			if(g_options.tile_image_effect_reverse == false)
10772				imageEffectClassAdd = " ug-trans-enabled";
10773			
10774			var imageOverlayHtml = "<div class='ug-tile-image-overlay"+imageEffectClassAdd+"' >";
10775			var imageEffectClass = " ug-"+g_options.tile_image_effect_type+"-effect";
10776			
10777			imageOverlayHtml += "<img src=\""+g_functions.escapeDoubleSlash(objItem.urlThumb)+"\" alt='"+objItem.title+"' class='"+imageEffectClass + imageEffectClassAdd+"'>";
10778			imageOverlayHtml += "</div>";
10779			
10780			objThumbWrapper.append(imageOverlayHtml);
10781
10782			//hide the image overlay if reversed
10783			if(g_options.tile_image_effect_reverse == true){
10784				objThumbWrapper.children(".ug-tile-image-overlay").fadeTo(0,0);
10785			}
10786			
10787		}
10788		
10789		
10790		//add text panel
10791		if(g_options.tile_enable_textpanel == true){
10792			
10793			var objTextPanel = new UGTextPanel();			 
10794			objTextPanel.init(g_gallery, g_options, "tile");
10795			
10796			//set transition class
10797			var textpanelAddClass = "";
10798			if(g_options.tile_textpanel_always_on == true || g_temp.isTextpanelOutside == true)
10799				textpanelAddClass = "ug-trans-enabled";
10800			
10801			objTextPanel.appendHTML(objThumbWrapper, textpanelAddClass);
10802			
10803			var panelTitle = objItem.title;
10804			var panelDesc = "";
10805			
10806			switch(g_options.tile_textpanel_source){
10807				case "desc":
10808				case "description":
10809					panelTitle = objItem.description;
10810				break;
10811				case "desc_title":
10812					if(objItem.description != "")
10813						panelTitle = objItem.description;
10814				break;
10815				case "title_and_desc":
10816					panelTitle = objItem.title;
10817					panelDesc = objItem.description;
10818				break;
10819			}
10820			
10821			objTextPanel.setTextPlain(panelTitle, panelDesc);
10822			
10823			if(g_options.tile_textpanel_always_on == false)
10824				objTextPanel.getElement().fadeTo(0,0);
10825			
10826			objThumbWrapper.data("objTextPanel", objTextPanel);
10827
10828			//if textpanel always on, it has to be under the overlay
10829			if(g_options.tile_textpanel_always_on == true){
10830				var textPanelElement = getTextPanelElement(objThumbWrapper);
10831				textPanelElement.css("z-index",2);
10832			}
10833			
10834			//if text panel is outside, clone textpanel
10835			if(g_temp.isTextpanelOutside == true){
10836				
10837				var htmlClone = "<div class='ug-tile-cloneswrapper'></div>";
10838				objThumbWrapper.append(htmlClone);
10839				var objCloneWrapper = objThumbWrapper.children(".ug-tile-cloneswrapper");
10840				
10841				var objTextPanelClone = new UGTextPanel(); 
10842				objTextPanelClone.init(g_gallery, g_options, "tile");				
10843				objTextPanelClone.appendHTML(objCloneWrapper);
10844				objTextPanelClone.setTextPlain(panelTitle, panelDesc);
10845				objThumbWrapper.data("objTextPanelClone", objTextPanelClone);
10846			}
10847			
10848		}
10849		
10850		//add additional html
10851		if(objItem.addHtml !== null)
10852			objThumbWrapper.append(objItem.addHtml);
10853		
10854	}
10855	
10856	
10857	/**
10858	 * load tile image, place the image on load
10859	 */
10860	this.loadTileImage = function(objTile){
10861		
10862		var objImage = t.getTileImage(objTile);
10863			
10864		g_functions.checkImagesLoaded(objImage, null, function(objImage,isError){
10865			onPlaceImage(null, objTile, jQuery(objImage));
10866		});
10867		
10868	}
10869	
10870	function _________________GETTERS________________(){};
10871	
10872	
10873	
10874	/**
10875	 * get image overlay
10876	 */
10877	function getTileOverlayImage(objTile){
10878		var objOverlayImage = objTile.children(".ug-tile-image-overlay");
10879		return(objOverlayImage);
10880	}
10881	
10882	/**
10883	 * get tile color overlay
10884	 */
10885	function getTileOverlay(objTile){
10886		var objOverlay = objTile.children(".ug-thumb-overlay");
10887		return(objOverlay);		
10888	}
10889	
10890	
10891	/**
10892	 * get image container
10893	 */
10894	function getTileImageContainer(objTile){
10895		if(g_temp.hasImageContainer == false)
10896			return(null);
10897		
10898		var objImageContainer = objTile.children(".ug-image-container");
10899		
10900		return(objImageContainer);
10901	}
10902	
10903	
10904	/**
10905	 * get image effect
10906	 */
10907	function getTileImageEffect(objTile){		
10908		var objImageEffect = objTile.find(".ug-tile-image-overlay img");			
10909		return(objImageEffect);
10910	}
10911	
10912	
10913	/**
10914	 * get text panel
10915	 */
10916	function getTextPanel(objTile){
10917		var objTextPanel = objTile.data("objTextPanel");
10918		
10919		return(objTextPanel);
10920	}
10921	
10922	
10923	/**
10924	 * get cloned text panel
10925	 */
10926	function getTextPanelClone(objTile){
10927		var objTextPanelClone = objTile.data("objTextPanelClone");
10928		
10929		return(objTextPanelClone);
10930		
10931	}
10932	
10933	
10934	/**
10935	 * get text panel element from the tile
10936	 */
10937	function getTextPanelElement(objTile){
10938		var objTextPanel = objTile.children(".ug-textpanel");
10939		
10940		return(objTextPanel);
10941	}
10942	
10943	
10944	/**
10945	 * get text panel element cloned
10946	 */
10947	function getTextPanelCloneElement(objTile){
10948		var objTextPanel = objTile.find(".ug-tile-cloneswrapper .ug-textpanel");
10949		
10950		if(objTextPanel.length == 0)
10951			throw new Error("text panel cloned element not found");
10952		
10953		return(objTextPanel);
10954		
10955	}
10956	
10957	
10958	/**
10959	 * get text panel height
10960	 */
10961	function getTextPanelHeight(objTile){
10962		
10963		if(g_temp.isTextpanelOutside == true)
10964			var objTextPanel = getTextPanelCloneElement(objTile);
10965		else
10966			var objTextPanel = getTextPanelElement(objTile);
10967		
10968		
10969		if(!objTextPanel)
10970			return(0);
10971		
10972		var objSize = g_functions.getElementSize(objTextPanel);
10973		return(objSize.height);
10974	}
10975	
10976	
10977	/**
10978	 * get button link
10979	 */
10980	function getButtonLink(objTile){
10981		var objButton = objTile.find(".ug-icon-link");
10982		if(objButton.length == 0)
10983			return(null);
10984		
10985		return objButton;
10986	}
10987
10988	
10989	/**
10990	 * get tile ratio
10991	 */
10992	function getTileRatio(objTile, fromWhere){
10993		
10994		//global ratio
10995		var ratio = g_temp.ratioByHeight;
10996		
10997		switch(g_options.tile_size_by){
10998			default:		//global ratio
10999				ratio = g_temp.ratioByHeight;
11000			break;
11001			case t.sizeby.IMAGE_RATIO:
11002
11003				if(!objTile)
11004					throw new Error("tile should be given for tile ratio");
11005				
11006				var item = t.getItemByTile(objTile);
11007								
11008				if(typeof item.thumbRatioByHeight != "undefined"){
11009					
11010					if(item.thumbRatioByHeight == 0){
11011						trace(item);
11012						throw new Error("the item ratio not inited yet");
11013					}
11014				
11015					ratio = item.thumbRatioByHeight;
11016				}
11017			
11018			break;
11019			case t.sizeby.CUSTOM:
11020				return null;
11021			break;
11022		}
11023				
11024		return(ratio);
11025	}
11026	
11027	
11028	/**
11029	 * get button zoom
11030	 */
11031	function getButtonZoom(objTile){
11032		var objButton = objTile.find(".ug-button-play");
11033		
11034		if(objButton.length == 0)
11035			return(null);
11036		
11037		return objButton;
11038	}
11039	
11040	
11041	/**
11042	 * tells if the tile is over style
11043	 */
11044	function isOverStyle(objTile){
11045		
11046		if(objTile.hasClass("ug-thumb-over"))
11047			return(true);
11048		
11049		return(false);
11050	}
11051	
11052	
11053	/**
11054	 * check if the tile is clickable
11055	 */
11056	function isTileClickable(objTile){
11057		
11058		return objTile.hasClass("ug-tile-clickable");
11059	}
11060	
11061	
11062	/**
11063	 * return if the items icon always on
11064	 */
11065	function isItemIconAlwaysOn(objItem){
11066		
11067		if(g_options.tile_enable_icons == true && g_temp.isVideoplayIconAlwaysOn == true && objItem.type != "image")
11068			return(true);
11069		
11070		return(false);
11071	}
11072
11073	
11074	function _________________SETTERS________________(){};
11075	
11076	
11077	/**
11078	 * position tile images elements
11079	 * width, height - tile width height
11080	 */
11081	function positionElements_images(objTile, width, height, visibleOnly){
11082		
11083		var objImageOverlay = getTileOverlayImage(objTile);
11084		var objThumbImage = t.getTileImage(objTile);
11085		var objImageEffect = getTileImageEffect(objTile);
11086		
11087		//reduce borders
11088		width -= g_temp.tileInnerReduce;
11089		height -= g_temp.tileInnerReduce;
11090		
11091		var imagePosy = null;
11092		
11093		//reduce textpanel height
11094		if(g_temp.isTextpanelOutside == true){
11095
11096			var textHeight = getTextPanelHeight(objTile);
11097			height -= textHeight;
11098
11099			if(g_options.tile_textpanel_position == "top"){
11100				imagePosy = textHeight;
11101			}
11102			
11103			/**
11104			 * if has image container
11105			 */
11106			if(g_temp.hasImageContainer == true){
11107				var objImageContainer = getTileImageContainer(objTile);
11108				g_functions.setElementSize(objImageContainer, width, height);
11109				
11110				if(imagePosy !== null)
11111					g_functions.placeElement(objImageContainer, 0, imagePosy);
11112			}
11113			
11114		}
11115		
11116		//scale image
11117		if(g_options.tile_enable_image_effect == false){
11118
11119			g_functions.scaleImageCoverParent(objThumbImage, width, height);
11120			
11121			if(g_temp.hasImageContainer == false && imagePosy !== null)
11122				g_functions.placeElement(objThumbImage, 0, imagePosy);
11123
11124		}else{	//width the effect
11125			
11126			//set what to resize
11127			var dontResize = "nothing";
11128			if(visibleOnly === true && g_temp.isTextpanelOutside == false){
11129				if(g_options.tile_image_effect_reverse == true){
11130					dontResize = "effect";
11131				}else{
11132					dontResize = "image";
11133				}
11134			}
11135
11136			//resize image effect
11137			if(dontResize != "effect"){
11138				g_functions.setElementSize(objImageOverlay, width, height);
11139				
11140				if(imagePosy !== null)
11141					g_functions.placeElement(objImageOverlay, 0, imagePosy);
11142				
11143				g_functions.scaleImageCoverParent(objImageEffect, width, height);
11144			}
11145			
11146
11147			//resize image
11148			if(dontResize != "image"){
11149				
11150				if(g_temp.hasImageContainer == true){
11151					g_functions.scaleImageCoverParent(objThumbImage, width, height);
11152				}else{
11153					
11154					//if can't clone, resize
11155					if(dontResize == "effect"){
11156						g_functions.scaleImageCoverParent(objThumbImage, width, height);
11157						if(imagePosy !== null)
11158							g_functions.placeElement(objThumbImage, 0, imagePosy);
11159					}
11160					else
11161						g_functions.cloneElementSizeAndPos(objImageEffect, objThumbImage, false, null, imagePosy);
11162					
11163				}
11164				
11165			}
11166
11167			
11168			
11169		}
11170
11171	}
11172	
11173	
11174	/**
11175	 * position text panel
11176	 * panelType - default or clone
11177	 */
11178	function positionElements_textpanel(objTile, panelType, tileWidth, tileHeight){
11179		
11180		var panelWidth = null;
11181		if(tileWidth)
11182			panelWidth = tileWidth - g_temp.tileInnerReduce;
11183
11184		if(tileHeight)
11185			tileHeight -= g_temp.tileInnerReduce;
11186		
11187		if(panelType == "clone"){
11188			var objTextPanelClone = getTextPanelClone(objTile);
11189			objTextPanelClone.refresh(true, true, panelWidth);
11190			var objItem = t.getItemByTile(objTile);
11191			objItem.textPanelCloneSizeSet = true;
11192			
11193			return(false);
11194		}
11195		
11196		var objTextPanel = getTextPanel(objTile);
11197		
11198		if(!objTextPanel)
11199			return(false);
11200		
11201		var panelHeight = null;
11202				
11203		//set panel height also
11204		if(g_temp.isTextpanelOutside == true)
11205			panelHeight = getTextPanelHeight(objTile);
11206		
11207		objTextPanel.refresh(false, true, panelWidth, panelHeight);
11208		
11209		var isPosition = (g_options.tile_textpanel_always_on == true || g_options.tile_textpanel_appear_type == "fade");
11210		
11211		if(isPosition){
11212			
11213			if(g_temp.isTextpanelOutside == true && tileHeight && g_options.tile_textpanel_position == "bottom"){
11214			
11215				var posy = tileHeight - panelHeight;
11216				objTextPanel.positionPanel(posy);
11217			}else
11218				objTextPanel.positionPanel();
11219		}
11220		
11221	}
11222		
11223	
11224	/**
11225	 * position the elements
11226	 */
11227	function positionElements(objTile){
11228		
11229		var objItem = t.getItemByTile(objTile);
11230		var objButtonZoom = getButtonZoom(objTile);
11231		var objButtonLink = getButtonLink(objTile);
11232		var sizeTile = g_functions.getElementSize(objTile);
11233				
11234		positionElements_images(objTile, sizeTile.width, sizeTile.height);
11235		
11236		//position text panel:
11237		if(g_options.tile_enable_textpanel == true)
11238			positionElements_textpanel(objTile, "regular", sizeTile.width, sizeTile.height);
11239		
11240		
11241		//position overlay:
11242		var overlayWidth = sizeTile.width - g_temp.tileInnerReduce;
11243		var overlayHeight = sizeTile.height - g_temp.tileInnerReduce;
11244		var overlayY = 0;
11245		if(g_temp.isTextpanelOutside == true){
11246			var textHeight = getTextPanelHeight(objTile);
11247			overlayHeight -= textHeight;
11248			if(g_options.tile_textpanel_position == "top")
11249				overlayY = textHeight;
11250		}
11251		
11252		var objOverlay = getTileOverlay(objTile);
11253		g_functions.setElementSizeAndPosition(objOverlay, 0, overlayY, overlayWidth, overlayHeight);
11254		
11255		//set vertical gap for icons
11256		if(objButtonZoom || objButtonLink){
11257
11258			var gapVert = 0;
11259			if( g_options.tile_enable_textpanel == true && g_temp.isTextPanelHidden == false && g_temp.isTextpanelOutside == false){
11260				var objTextPanelElement = getTextPanelElement(objTile);
11261				var texPanelSize = g_functions.getElementSize(objTextPanelElement);
11262				if(texPanelSize.height > 0)
11263					gapVert = Math.floor((texPanelSize.height / 2) * -1);
11264			}
11265
11266		}
11267		
11268		if(objButtonZoom && objButtonLink){
11269			var sizeZoom = g_functions.getElementSize(objButtonZoom);
11270			var sizeLink = g_functions.getElementSize(objButtonLink);
11271			var spaceBetween = g_options.tile_space_between_icons;
11272			
11273			var buttonsWidth = sizeZoom.width + spaceBetween + sizeLink.width;
11274			var buttonsX = Math.floor((sizeTile.width - buttonsWidth) / 2);
11275			
11276			//trace("X: "+buttonsX+" "+"space: " + spaceBetween);
11277			
11278			//if space more then padding, calc even space.
11279			if(buttonsX < spaceBetween){
11280				spaceBetween = Math.floor((sizeTile.width - sizeZoom.width - sizeLink.width) / 3);
11281				buttonsWidth = sizeZoom.width + spaceBetween + sizeLink.width;
11282				buttonsX = Math.floor((sizeTile.width - buttonsWidth) / 2);
11283			}
11284
11285			g_functions.placeElement(objButtonZoom, buttonsX, "middle", 0 ,gapVert);
11286			g_functions.placeElement(objButtonLink, buttonsX + sizeZoom.width + spaceBetween, "middle", 0, gapVert);
11287						
11288		}else{
11289			
11290			if(objButtonZoom)
11291				g_functions.placeElement(objButtonZoom, "center", "middle", 0, gapVert);
11292			
11293			if(objButtonLink)
11294				g_functions.placeElement(objButtonLink, "center", "middle", 0, gapVert);
11295				
11296		}
11297		
11298		if(objButtonZoom)
11299			objButtonZoom.show();
11300		
11301		if(objButtonLink)
11302			objButtonLink.show();
11303	}
11304
11305	
11306	/**
11307	 * set tiles htmls
11308	 */
11309	this.setHtml = function(objParent){
11310		g_objParentWrapper = objParent;
11311		
11312		modifyOptionsBeforeRender();
11313		
11314		g_thumbs.setHtmlThumbs(objParent);
11315	}
11316	
11317	
11318	/**
11319	 * set the overlay effect
11320	 */
11321	function setImageOverlayEffect(objTile, isActive){
11322		
11323		var objItem = t.getItemByTile(objTile);
11324		var objOverlayImage = getTileOverlayImage(objTile);
11325		
11326		var animationDuration = g_options.thumb_transition_duration;
11327		
11328		if(g_options.tile_image_effect_reverse == false){
11329			
11330			var objThumbImage = t.getTileImage(objTile);
11331			
11332			if(isActive){
11333				objThumbImage.fadeTo(0,1);			
11334				objOverlayImage.stop(true).fadeTo(animationDuration, 0);
11335			}
11336			else
11337				objOverlayImage.stop(true).fadeTo(animationDuration, 1);
11338			
11339		}else{
11340			
11341			if(isActive){
11342				objOverlayImage.stop(true).fadeTo(animationDuration, 1);
11343			}
11344			else{
11345				objOverlayImage.stop(true).fadeTo(animationDuration, 0);
11346			}
11347		}
11348
11349	}
11350	
11351	
11352	/**
11353	 * set textpanel effect
11354	 */
11355	function setTextpanelEffect(objTile, isActive){
11356		
11357		var animationDuration = g_options.thumb_transition_duration;
11358		
11359		var objTextPanel = getTextPanelElement(objTile);
11360		if(!objTextPanel)
11361			return(true);
11362				
11363		if(g_options.tile_textpanel_appear_type == "slide"){
11364			
11365			var panelSize = g_functions.getElementSize(objTextPanel);
11366			if(panelSize.width == 0)
11367				return(false);
11368			
11369			var startPos = -panelSize.height;
11370			var endPos = 0;
11371			var startClass = {}, endClass = {};
11372			
11373			var posName = "bottom";
11374			if(g_options.tile_textpanel_position == "inside_top")
11375				posName = "top";
11376			
11377			startClass[posName] = startPos+"px";
11378			endClass[posName] = endPos+"px";
11379						
11380			if(isActive == true){
11381								
11382				objTextPanel.fadeTo(0,1);
11383				
11384				if(objTextPanel.is(":animated") == false)
11385					objTextPanel.css(startClass);
11386				
11387				endClass["opacity"] = 1;
11388					
11389				objTextPanel.stop(true).animate(endClass, animationDuration);
11390				
11391			}else{
11392				
11393				objTextPanel.stop(true).animate(startClass, animationDuration);
11394				
11395			}
11396			
11397		}else{		//fade effect
11398			
11399			if(isActive == true){
11400				objTextPanel.stop(true).fadeTo(animationDuration, 1);
11401			}else{
11402				objTextPanel.stop(true).fadeTo(animationDuration, 0);
11403			}
11404			
11405		}
11406		
11407	}
11408	
11409
11410	/**
11411	 * set thumb border effect
11412	 */
11413	function setIconsEffect(objTile, isActive, noAnimation){
11414		
11415		var animationDuration = g_options.thumb_transition_duration;
11416		if(noAnimation && noAnimation === true)
11417			animationDuration = 0;
11418		
11419		var g_objIconZoom = getButtonZoom(objTile);
11420		var g_objIconLink = getButtonLink(objTile);
11421		var opacity = isActive?1:0;
11422		
11423		if(g_objIconZoom)
11424			g_objIconZoom.stop(true).fadeTo(animationDuration, opacity);
11425		
11426		if(g_objIconLink)
11427			g_objIconLink.stop(true).fadeTo(animationDuration, opacity);
11428		
11429	}
11430	
11431	
11432	
11433	/**
11434	 * set tile over style
11435	 */
11436	function setOverStyle(data, objTile){
11437				
11438		objTile = jQuery(objTile);
11439				
11440		if(g_options.tile_enable_image_effect)
11441			setImageOverlayEffect(objTile, true);
11442
11443		if(g_options.tile_enable_textpanel == true && g_options.tile_textpanel_always_on == false && g_temp.isTextPanelHidden == false)
11444			setTextpanelEffect(objTile, true);
11445		
11446		//show/hide icons - if saparate (if not, they are part of the overlay)
11447		//if the type is video and icon always on - the icon should stay
11448		if(g_temp.isSaparateIcons && g_options.tile_enable_icons == true){
11449			var isSet = (g_options.thumb_overlay_reverse == true);
11450			
11451			var objItem = t.getItemByTile(objTile);
11452			if(isItemIconAlwaysOn(objItem) == false)
11453				setIconsEffect(objTile, isSet, false);
11454			
11455		}
11456		
11457	}
11458	
11459	
11460	/**
11461	 * set normal style
11462	 */
11463	function setNormalStyle(data, objTile){
11464		
11465		objTile = jQuery(objTile);
11466		
11467		if(g_options.tile_enable_image_effect)
11468			setImageOverlayEffect(objTile, false);
11469		
11470		if(g_options.tile_enable_textpanel == true && g_options.tile_textpanel_always_on == false)
11471			setTextpanelEffect(objTile, false);
11472		
11473		//show/hide icons - if saparate (if not, they are part of the overlay)
11474		if(g_temp.isSaparateIcons == true && g_options.tile_enable_icons == true){
11475			
11476			var isSet = (g_options.thumb_overlay_reverse == true)?false:true;
11477			
11478			var objItem = t.getItemByTile(objTile);
11479			if(isItemIconAlwaysOn(objItem) == false)
11480				setIconsEffect(objTile, isSet, false);
11481			else{	//make icon always appear
11482				setIconsEffect(objTile, true, true);
11483			}
11484			
11485		}
11486		
11487	}
11488	
11489	
11490	/**
11491	 * set all tiles normal style
11492	 */
11493	function setAllTilesNormalStyle(objTileExcept){
11494		
11495		var objTiles = g_thumbs.getThumbs().not(objTileExcept);
11496		objTiles.each(function(index, objTile){
11497			g_thumbs.setThumbNormalStyle(jQuery(objTile));
11498		});
11499		
11500	}
11501	
11502	
11503	function _________________EVENTS________________(){};
11504	
11505	
11506	/**
11507	 * on tile size change, place elements
11508	 */
11509	function onSizeChange(data, objTile, forcePosition){
11510
11511		objTile = jQuery(objTile);
11512		
11513		//position elements only if the image loaded (placed)
11514		if(g_options.tile_visible_before_image == true && objTile.data("image_placed") !== true && forcePosition !== true)
11515			return(true);
11516
11517		positionElements(objTile);
11518		
11519		g_thumbs.setThumbNormalStyle(objTile);
11520	}
11521	
11522	
11523	/**
11524	 * on place image event after images loaded
11525	 */
11526	function onPlaceImage(data, objTile, objImage){
11527		
11528		positionElements(objTile);
11529		objImage.fadeTo(0,1);
11530		
11531		objTile.data("image_placed", true);
11532	}
11533	
11534	
11535	/**
11536	 * on tile click on mobile devices on normal state
11537	 * set the tile over state
11538	 */
11539	function onMobileClick(objTile){
11540
11541		if(isTileClickable(objTile) == true){
11542			g_objThis.trigger(t.events.TILE_CLICK, objTile);
11543			return(true);
11544		}
11545		
11546		if(isOverStyle(objTile) == false){
11547			setAllTilesNormalStyle(objTile);			
11548			g_thumbs.setThumbOverStyle(objTile);
11549		}
11550		
11551	}
11552	
11553	
11554	/**
11555	 * on tile click event
11556	 */
11557	function onTileClick(event){
11558				
11559		var objTile = jQuery(this);
11560		
11561		var tagname = objTile.prop("tagName").toLowerCase();
11562		var isApproved = true;
11563		if(g_temp.funcParentApproveClick && g_temp.funcParentApproveClick() == false)
11564			isApproved = false;
11565				
11566		if(tagname == "a"){
11567			
11568			if(isApproved == false)
11569				event.preventDefault();
11570							
11571		}else{		//in case of div
11572			
11573			if(isOverStyle(objTile) == false){	//mobile click version
11574				
11575				if(isApproved == true)
11576					onMobileClick(objTile);
11577								
11578			}else{
11579				if(isTileClickable(objTile) == false)
11580					return(true);
11581				
11582				if(isApproved == true)
11583					g_objThis.trigger(t.events.TILE_CLICK, objTile);
11584			}
11585			
11586			
11587		}
11588		
11589	}
11590	
11591	
11592	/**
11593	 * click on zoom button (as tile click)
11594	 */
11595	function onZoomButtonClick(event){
11596				
11597		event.stopPropagation();
11598		
11599		var objTile = jQuery(this).parents(".ug-tile");
11600		
11601		var isApproved = true;
11602		
11603		if(g_temp.funcParentApproveClick && g_temp.funcParentApproveClick() == false)
11604			isApproved = false;
11605		
11606		if(isOverStyle(objTile) == false){
11607			onMobileClick(objTile);
11608			return(true);
11609		}
11610			
11611		if(isApproved == true){
11612			g_objThis.trigger(t.events.TILE_CLICK, objTile);
11613			return(false);
11614		}
11615		
11616	}
11617	
11618	
11619	/**
11620	 * on link icon click
11621	 */
11622	function onLinkButtonClick(event){
11623		var objTile = jQuery(this).parents(".ug-tile");
11624				
11625		if(g_temp.funcParentApproveClick && g_temp.funcParentApproveClick() == false)
11626			event.preventDefault();
11627		
11628		//allow click only from over style
11629		if(isOverStyle(objTile) == false && g_options.tile_as_link == false){
11630			event.preventDefault();
11631			onMobileClick(objTile);
11632		}
11633		
11634	}
11635	
11636	
11637	/**
11638	 * init events
11639	 */
11640	this.initEvents = function(){
11641				
11642		g_thumbs.initEvents();
11643		
11644		//connect the over and normal style of the regular thumbs
11645		jQuery(g_thumbs).on(g_thumbs.events.SETOVERSTYLE, setOverStyle);
11646		jQuery(g_thumbs).on(g_thumbs.events.SETNORMALSTYLE, setNormalStyle);
11647		jQuery(g_thumbs).on(g_thumbs.events.PLACEIMAGE, onPlaceImage);
11648		
11649		g_objWrapper.on(g_temp.eventSizeChange, onSizeChange);
11650		
11651		g_objParentWrapper.delegate(".ug-tile .ug-button-play", "click", onZoomButtonClick);
11652		
11653		g_objParentWrapper.delegate(".ug-tile", "click", onTileClick);
11654		
11655		g_objParentWrapper.delegate(".ug-tile .ug-icon-link", "click", onLinkButtonClick);
11656	}
11657	
11658	
11659	/**
11660	 * destroy the element events
11661	 */
11662	this.destroy = function(){
11663				
11664		jQuery(g_thumbs).off(g_thumbs.events.SETOVERSTYLE);
11665		jQuery(g_thumbs).off(g_thumbs.events.SETNORMALSTYLE);
11666		jQuery(g_thumbs).off(g_thumbs.events.PLACEIMAGE);
11667		g_objWrapper.off(g_temp.eventSizeChange);
11668		
11669		if(g_options.tile_enable_textpanel == true){
11670			var objThumbs = g_thumbs.getThumbs();
11671			jQuery.each(objThumbs, function(index, thumb){				
11672				var textPanel = getTextPanel(jQuery(thumb));
11673				if(textPanel)
11674					textPanel.destroy();
11675			});
11676		}
11677		
11678		g_thumbs.destroy();
11679
11680	}
11681
11682	
11683	/**
11684	 * external init
11685	 */
11686	this.init = function(gallery, g_thumbs, customOptions){
11687		
11688		init(gallery, g_thumbs, customOptions);
11689	}
11690	
11691	/**
11692	 * set fixed mode
11693	 */
11694	this.setFixedMode = function(){
11695		
11696		g_options.tile_size_by = t.sizeby.GLOBAL_RATIO;
11697		g_options.tile_visible_before_image = true;
11698	}
11699	
11700	
11701	/**
11702	 * set parent approve click function
11703	 */
11704	this.setApproveClickFunction = function(funcApprove){
11705		g_temp.funcParentApproveClick = funcApprove;
11706	}
11707	
11708	
11709	
11710	/**
11711	 * resize tile. If no size given, resize to original size
11712	 * the resize mode taken from resize modes constants, default is full
11713	 */
11714	this.resizeTile = function(objTile, newWidth, newHeight, resizeMode){
11715		
11716			//if textpanel outside - refresh the textpanel first
11717			if(g_temp.isTextpanelOutside == true)
11718				positionElements_textpanel(objTile, "clone", newWidth);
11719			
11720			if(!newWidth){
11721				
11722				var newWidth = g_options.tile_width;
11723				var newHeight = g_options.tile_height;
11724				
11725			}else{		//only height is missing
11726				if(!newHeight){
11727					
11728					var newHeight = t.getTileHeightByWidth(newWidth, objTile, "resizeTile");
11729				}
11730			}
11731						
11732			g_functions.setElementSize(objTile, newWidth, newHeight);
11733			
11734			switch(resizeMode){
11735				default:
11736				case t.resizemode.FULL:
11737					t.triggerSizeChangeEvent(objTile, true);
11738				break;
11739				case t.resizemode.WRAPPER_ONLY:
11740					return(true);
11741				break;
11742				case t.resizemode.VISIBLE_ELEMENTS:
11743					
11744					if(g_temp.funcCustomTileHtml){
11745						t.triggerSizeChangeEvent(objTile, true);
11746						return(true);
11747					}
11748					
11749					//resize images
11750					positionElements_images(objTile, newWidth, newHeight, true);
11751					
11752					//resize text panel, if visible
11753					if(g_options.tile_enable_textpanel == true && g_options.tile_textpanel_always_on == true && newWidth){
11754						positionElements_textpanel(objTile, "regular", newWidth, newHeight);
11755					}
11756					
11757				break;
11758			}
11759		
11760	}
11761
11762	
11763	/**
11764	 * resize all tiles 
11765	 */
11766	this.resizeAllTiles = function(newWidth, resizeMode){
11767		
11768		modifyOptionsBeforeRender();
11769		
11770		var newHeight = null;
11771		
11772		if(g_options.tile_size_by == t.sizeby.GLOBAL_RATIO)
11773			newHeight = t.getTileHeightByWidth(newWidth,null,"resizeAllTiles");
11774		
11775		var objTiles = g_thumbs.getThumbs();
11776		objTiles.each(function(index, objTile){
11777			t.resizeTile(jQuery(objTile), newWidth, newHeight, resizeMode);
11778		});
11779		
11780	}
11781	
11782	
11783	/**
11784	 * trigger size change events
11785	 * the force is only for fixed size mode
11786	 */
11787	this.triggerSizeChangeEvent = function(objTile, isForce){
11788		
11789		if(!objTile)
11790			return(false);
11791		
11792		if(!isForce)
11793			var isForce = false;
11794		
11795		g_objWrapper.trigger(g_temp.eventSizeChange, [objTile, isForce]);
11796		
11797	}
11798	
11799	
11800	/**
11801	 * trigger size change event to all tiles
11802	 * the force is only for fixed mode
11803	 */
11804	this.triggerSizeChangeEventAllTiles = function(isForce){
11805		
11806		var objThumbs = g_thumbs.getThumbs();
11807
11808		objThumbs.each(function(){
11809			var objTile = jQuery(this);
11810			
11811			t.triggerSizeChangeEvent(objTile, isForce);
11812			
11813		});
11814		
11815	}
11816	
11817	
11818	
11819	
11820	
11821	/**
11822	 * disable all events
11823	 */
11824	this.disableEvents = function(){
11825		var objThumbs = g_thumbs.getThumbs();
11826		objThumbs.css("pointer-events", "none");
11827	}
11828	
11829	
11830	/**
11831	 * enable all events
11832	 */
11833	this.enableEvents = function(){
11834		var objThumbs = g_thumbs.getThumbs();
11835		objThumbs.css("pointer-events", "auto");
11836	}
11837	
11838	/**
11839	 * set new options
11840	 */
11841	this.setOptions = function(newOptions){
11842		g_options = jQuery.extend(g_options, newOptions);
11843		g_thumbs.setOptions(newOptions);
11844	}
11845	
11846	
11847	/**
11848	 * set new tile size, this function will not resize, and keep ratio
11849	 */
11850	this.setTileSizeOptions = function(newTileWidth){
11851		
11852		if(g_options.tile_size_by !== t.sizeby.GLOBAL_RATIO)
11853			throw new Error("setNewTileOptions works with global ration only");
11854		
11855		g_options.tile_width = newTileWidth;
11856		g_options.tile_height = Math.floor(newTileWidth * g_temp.ratioByHeight);
11857		
11858		
11859	}
11860	
11861	
11862	/**
11863	 * set custom tile html function
11864	 */
11865	this.setCustomFunctions = function(funcCustomHtml, funcPositionElements){
11866		g_temp.funcCustomTileHtml = funcCustomHtml;
11867		g_temp.funcCustomPositionElements = funcPositionElements;
11868	}
11869	
11870	
11871	/**
11872	 * run the tile design
11873	 */
11874	this.run = function(){
11875		
11876		//resize all tiles
11877		var objThumbs = g_thumbs.getThumbs();
11878		
11879		if(g_options.tile_size_by == t.sizeby.GLOBAL_RATIO){
11880			t.resizeAllTiles(g_options.tile_width, t.resizemode.WRAPPER_ONLY);
11881		}
11882			
11883		//hide original image if image effect active
11884		if(g_options.tile_enable_image_effect == true && g_options.tile_image_effect_reverse == false)
11885			objThumbs.children(".ug-thumb-image").fadeTo(0,0);
11886		
11887		g_thumbs.setHtmlProperties();
11888		
11889		if(g_options.tile_visible_before_image == true){
11890			
11891			//if textpanel outside - refresh the textpanel first			
11892			objThumbs.children(".ug-thumb-image").fadeTo(0,0);
11893			g_thumbs.loadThumbsImages();
11894		}
11895		
11896	}
11897
11898	
11899	this._____________EXTERNAL_GETTERS____________=function(){};
11900	
11901	
11902	/**
11903	 * get thumbs general option
11904	 */
11905	this.getObjThumbs = function(){
11906		return g_thumbs;
11907	}
11908	
11909	/**
11910	 * get options
11911	 */
11912	this.getOptions = function(){
11913		return g_options;
11914	}
11915
11916	/**
11917	 * get tile image
11918	 */
11919	this.getTileImage = function(objTile){
11920		var objImage = objTile.find("img.ug-thumb-image");
11921		return(objImage);
11922	}
11923
11924	
11925	/**
11926	 * get item from tile
11927	 */
11928	this.getItemByTile = function(objTile){
11929		return g_thumbs.getItemByThumb(objTile);
11930	}
11931	
11932	
11933	/**
11934	 * get tile height by width
11935	 */
11936	this.getTileHeightByWidth = function(newWidth, objTile, fromWhere){
11937		
11938		var ratio = getTileRatio(objTile, fromWhere);
11939		
11940		if(ratio === null)
11941			return(null);
11942		
11943		var height = Math.floor( (newWidth - g_temp.tileInnerReduce) * ratio) + g_temp.tileInnerReduce;
11944		
11945		if(objTile && g_temp.isTextpanelOutside == true && g_options.tile_size_by == t.sizeby.IMAGE_RATIO)
11946			height += getTextPanelHeight(objTile);
11947		
11948		return(height);
11949	}
11950	
11951	
11952	/**
11953	 * get tile original size
11954	 */
11955	this.getTileImageSize = function(objTile){
11956        var objItem = t.getItemByTile(objTile);
11957        if(!objItem.thumbWidth || !objItem.thumbHeight)
11958        	throw new Error("Can't get image size - image not inited.");
11959        
11960        var objSize = {
11961        		width: objItem.thumbWidth,
11962        		height: objItem.thumbHeight
11963        };
11964        
11965        return(objSize);
11966	}
11967	
11968	
11969	/**
11970	 * get tile size
11971	 */
11972	this.getGlobalTileSize = function(){
11973		
11974		if(g_options.tile_size_by != t.sizeby.GLOBAL_RATIO)
11975			throw new Error("The size has to be global ratio");
11976		
11977		var objSize = {
11978				width: g_options.tile_width,
11979				height: g_options.tile_height
11980		};
11981		
11982		return(objSize);
11983	}
11984	
11985	
11986}
11987
11988/**
11989 * avia control class
11990 * addon to strip gallery
11991 */
11992function UGAviaControl(){
11993
11994	var g_parent, g_gallery, g_objects, g_objStrip, g_objStripInner, g_options;
11995	var g_isVertical;
11996	
11997	var g_temp = {
11998		touchEnabled:false,			//variable that tells if touch event was before move event
11999		isMouseInsideStrip: false,
12000		strip_finalPos:0,
12001		handle_timeout:"",
12002		isStripMoving:false,
12003		isControlEnabled: true
12004	};
12005	
12006	
12007	/**
12008	 * enable the control
12009	 */
12010	this.enable = function(){
12011		g_temp.isControlEnabled = true;
12012	}
12013	
12014	/**
12015	 * disable the control
12016	 */
12017	this.disable = function(){
12018		g_temp.isControlEnabled = false;		
12019	}
12020	
12021	/**
12022	 * init function for avia controls
12023	 */
12024	this.init = function(objParent){
12025		g_parent = objParent;
12026		
12027		g_objects = objParent.getObjects();
12028				
12029		g_gallery = g_objects.g_gallery;
12030		
12031		g_objStrip = g_objects.g_objStrip;
12032		g_objStripInner = g_objects.g_objStripInner;
12033		g_options = g_objects.g_options;
12034		g_isVertical = g_objects.isVertical;		
12035				
12036		initEvents();
12037	}
12038	
12039	/**
12040	 * get mouse position from event according the orientation
12041	 */
12042	function getMousePos(event){
12043		
12044		if(g_isVertical == false)
12045			return(event.pageX);
12046		
12047		return(event.pageY);
12048	}
12049	
12050	/**
12051	 * handle avia strip control event on body mouse move
12052	 */
12053	function initEvents(event){
12054		
12055		//make sure that the avia control will not work on touch devices
12056		jQuery("body").on("touchstart", function(event){
12057			
12058			if(g_temp.isControlEnabled == false)
12059				return(true);
12060			
12061			g_temp.touchEnabled = true;
12062			
12063		});
12064		
12065		//on body move
12066		jQuery("body").mousemove(function(event){
12067			
12068			if(g_temp.isControlEnabled == false)
12069				return(true);
12070									
12071			//protection for touch devices, disable the avia events
12072			if(g_temp.touchEnabled == true){
12073				jQuery("body").off("mousemove");
12074				return(true);
12075			}
12076			
12077			g_temp.isMouseInsideStrip = g_objStrip.ismouseover();
12078			var strip_touch_active = g_parent.isTouchMotionActive();
12079			
12080			if(g_temp.isMouseInsideStrip == true && strip_touch_active == false){
12081				
12082				var mousePos = getMousePos(event);
12083				
12084				moveStripToMousePosition(mousePos);
12085			}else{
12086				stopStripMovingLoop();
12087			}
12088			
12089		});
12090						
12091	}
12092	
12093	
12094	/**
12095	 * destroy the avia control events
12096	 */
12097	this.destroy = function(){
12098		
12099		jQuery("body").off("touchstart");
12100		jQuery("body").off("mousemove");
12101
12102	}
12103	
12104	
12105	/**
12106	 * get inner y position according mouse y position on the strip
12107	 */
12108	function getInnerPosY(mouseY){
12109
12110		var innerOffsetTop = g_options.strip_padding_top;
12111		var innerOffsetBottom = g_options.strip_padding_bottom;
12112
12113		var stripHeight = g_objStrip.height();
12114		var innerHeight = g_objStripInner.height();		
12115		
12116		//if all thumbs visible, no need to move
12117		if(stripHeight >
12117 innerHeight)
12118			return(null);
12119		
12120		//find y position inside the strip
12121		var stripOffset = g_objStrip.offset();		
12122		var offsetY = stripOffset.top;
12123		var posy = mouseY - offsetY - innerOffsetTop;
12124		if(posy < 0)
12125			return(null);
12126		
12127		//set measure line parameters
12128		var mlineStart = g_options.thumb_height;
12129		var mlineEnd = stripHeight - g_options.thumb_height;
12130		var mLineSize = mlineEnd - mlineStart;
12131				
12132		//fix position borders on the measure line
12133		if(posy < mlineStart)
12134			posy = mlineStart;
12135		
12136		if(posy > mlineEnd)
12137			posy = mlineEnd;
12138		
12139		//count the ratio of the position on the measure line
12140		var ratio = (posy - mlineStart) / mLineSize;
12141		var innerPosY = (innerHeight - stripHeight) * ratio;
12142		innerPosY = Math.round(innerPosY) * -1 + innerOffsetTop;
12143		
12144		return(innerPosY);
12145	}
12146
12147	
12148	/**
12149	 * get inner x position according mouse x position on the strip
12150	 */
12151	function getInnerPosX(mouseX){
12152		
12153		var innerOffsetLeft = g_options.strip_padding_left;
12154		var innerOffsetRight = g_options.strip_padding_right;
12155		
12156		var stripWidth = g_objStrip.width() - innerOffsetLeft - innerOffsetRight;
12157		var innerWidth = g_objStripInner.width();
12158		
12159		//if all thumbs visible, no need to move
12160		if(stripWidth > innerWidth)
12161			return(null);
12162		
12163		var stripOffset = g_objStrip.offset();
12164		var offsetX = stripOffset.left;
12165		var posx = mouseX - offsetX - innerOffsetLeft;
12166		
12167		//set measure line parameters
12168		var mlineStart = g_options.thumb_width;
12169		var mlineEnd = stripWidth - g_options.thumb_width;
12170		var mLineSize = mlineEnd - mlineStart;
12171		
12172		//fix position borders on the measure line
12173		if(posx < mlineStart)
12174			posx = mlineStart;
12175		
12176		if(posx > mlineEnd)
12177			posx = mlineEnd;
12178		
12179		//count the ratio of the position on the measure line
12180		var ratio = (posx - mlineStart) / mLineSize;
12181		var innerPosX = (innerWidth - stripWidth) * ratio;
12182		innerPosX = Math.round(innerPosX) * -1 + innerOffsetLeft;
12183		
12184		
12185		return(innerPosX);
12186	}
12187		
12188		
12189	/**
12190	 * move strip stap to final position
12191	 */
12192	function moveStripStep(){
12193		
12194		if(g_temp.is_strip_moving == false){
12195			return(false);
12196		}
12197		
12198		var innerPos = g_parent.getInnerStripPos();
12199				
12200		if(Math.floor(innerPos) == Math.floor(g_temp.strip_finalPos)){
12201			stopStripMovingLoop();
12202		}
12203		
12204		//calc step
12205		var diff = Math.abs(g_temp.strip_finalPos - innerPos);
12206		
12207		var dpos;
12208		if(diff < 1){
12209			dpos = diff;
12210		}
12211		else{
12212		
12213			dpos = diff / 4;
12214			if(dpos > 0 && dpos < 1)
12215				dpos = 1;
12216		}		
12217		
12218		if(g_temp.strip_finalPos < innerPos)
12219			dpos = dpos * -1;
12220				
12221		var newPos = innerPos + dpos;
12222		
12223		g_parent.positionInnerStrip(newPos);
12224		
12225	}
12226	
12227	
12228	/**
12229	 * start loop of strip moving
12230	 */
12231	function startStripMovingLoop(){
12232		
12233		if(g_temp.isStripMoving == true)
12234			return(false);
12235			
12236		g_temp.isStripMoving = true;
12237		g_temp.handle_timeout = setInterval(moveStripStep,10);
12238	}
12239	
12240	/**
12241	 * stop loop of strip moving
12242	 */
12243	function stopStripMovingLoop(){
12244		
12245		if(g_temp.isStripMoving == false)
12246			return(false);
12247			
12248		g_temp.isStripMoving = false;
12249		g_temp.handle_timeout = clearInterval(g_temp.handle_timeout);
12250	}
12251
12252	/**
12253	 * get inner position according the orientation
12254	 * taken by the mouse position
12255	 */
12256	function getInnerPos(mousePos){
12257		
12258		if(g_isVertical == false)
12259			return getInnerPosX(mousePos);
12260		else
12261			return getInnerPosY(mousePos);
12262		
12263	}
12264	
12265	
12266	/**
12267	 * move the strip to mouse position on it
12268	 * mousex - mouse position relative to the document
12269	 */
12270	function moveStripToMousePosition(mousePos){		
12271		
12272		var innerPos = getInnerPos(mousePos);
12273		
12274		if(innerPos === null)
12275			return(false);
12276		
12277		g_temp.is_strip_moving = true;
12278		g_temp.strip_finalPos = innerPos;
12279				
12280		startStripMovingLoop();
12281	}
12282	
12283}
12284
12285/**
12286 * slider class
12287 * addon to strip gallery
12288 */
12289function UGSlider(){
12290	
12291	var t = this, g_objThis = jQuery(t);
12292	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objWrapper, g_objThumbs;	
12293	//the video arrows is independent arrows that is not sitting on the controls
12294	var g_objSlider, g_objInner, g_objSlide1, g_objSlide2, g_objSlide3, g_objArrowLeft, g_objArrowRight;
12295	var g_objTouchSlider, g_objZoomSlider, g_objZoomPanel, g_objButtonPlay = null, g_objButtonFullscreen = null, g_objBullets = null;
12296	var g_objVideoPlayer = new UGVideoPlayer(), g_optionsPrefix;
12297	var g_functions = new UGFunctions(), g_objProgress = null, g_objTextPanel = null;
12298	
12299	
12300	this.events = {		
12301		ITEM_CHANGED: "item_changed",				//on item changed
12302		BEFORE_SWITCH_SLIDES: "before_switch",		//before slides switching
12303		BEFORE_RETURN: "before_return",				//before return from pan or from zoom
12304		AFTER_RETURN: "after_return",				//after return from pan or from zoom
12305		ZOOM_START: "slider_zoom_start",			//on zoom start 
12306		ZOOM_END: "slider_zoom_end",				//on zoom move 
12307		ZOOMING: "slider_zooming",					//on zooming
12308		ZOOM_CHANGE: "slider_zoom_change",			//on slide image image zoom change	
12309		START_DRAG: "start_drag",					//on slider drag start
12310		AFTER_DRAG_CHANGE: "after_drag_change",		//after finish drag chagne transition
12311		ACTION_START: "action_start",				//on slide action start
12312		ACTION_END: "action_end",					//on slide action stop
12313		CLICK: "slider_click",						//on click event
12314		TRANSITION_START:"slider_transition_start",	//before transition start event
12315		TRANSITION_END:"slider_transition_end",		//on transition end event
12316		AFTER_PUT_IMAGE: "after_put_image",			//after put slide image
12317		IMAGE_MOUSEENTER: "slider_image_mouseenter", //on slide image mouseonter
12318		IMAGE_MOUSELEAVE: "slider_image_mouseleave",	 		//on slide image mouseleave
12319		CURRENTSLIDE_LOAD_START: "slider_current_loadstart",	//on current slide load image start
12320		CURRENTSLIDE_LOAD_END: "slider_current_loadend"		//on finish load current slide image
12321	}
12322	
12323	var g_options = {
12324		  slider_scale_mode: "fill",					//fit: scale down and up the image to always fit the slider
12325		  												//down: scale down only, smaller images will be shown, don't enlarge images (scale up)
12326		  												//fill: fill the entire slider space by scaling, cropping and centering the image
12327		  												//fitvert: make the image always fill the vertical slider area
12328		  slider_scale_mode_media: "fill",				//fill, fit, down, fitvert - scale mode on media items
12329		  slider_scale_mode_fullscreen: "down",			//fill, fit, down, fitvert - scale mode on fullscreen.
12330		  		  
12331		  slider_item_padding_top: 0,					//padding top of the slider item
12332		  slider_item_padding_bottom: 0,				//padding bottom of the slider item
12333		  slider_item_padding_left: 0,					//padding left of the slider item
12334		  slider_item_padding_right: 0,					//padding right of the slider item
12335		  
12336		  slider_background_color: "",					//slider background color, set if you want to change default
12337		  slider_background_opacity: 1,					//slider background opacity
12338		  
12339		  slider_image_padding_top: 0,					//padding top of the image inside the item
12340		  slider_image_padding_bottom: 0,				//padding bottom of the image inside the item
12341		  slider_image_padding_left: 0,					//padding left of the image inside the item
12342		  slider_image_padding_right: 0,				//padding right of the image inside the item
12343
12344		  slider_image_border: false,					//enable border around the image
12345		  slider_image_border_width: 10,				//image border width
12346		  slider_image_border_color: "#ffffff",			//image border color
12347		  slider_image_border_radius: 0,				//image border radius
12348		  slider_image_border_maxratio: 0.35,			//max ratio that the border can take from the image
12349		  slider_image_shadow: false,					//enable border shadow the image
12350		  
12351		  slider_video_constantsize: false, 			//constant video size mode for video items
12352		  slider_video_constantsize_scalemode: "fit", 	//fit,down: constant video size scale mode
12353		  slider_video_constantsize_width: 854,			//constant video size width
12354		  slider_video_constantsize_height: 480,		//constant video size height
12355		  
12356		  slider_video_padding_top: 0,					//padding top of the video player inside the item
12357		  slider_video_padding_bottom: 0,				//padding bottom of the video player inside the item
12358		  slider_video_padding_left: 0,					//padding left of the video player inside the item
12359		  slider_video_padding_right: 0,				//padding right of the video player inside the item
12360		  
12361		  slider_video_enable_closebutton: true,		//enable video close button
12362		  
12363		  slider_transition: "slide",					//fade, slide - the transition of the slide change
12364		  slider_transition_speed:300,				 	//transition duration of slide change
12365		  slider_transition_easing: "easeInOutQuad",	//transition easing function of slide change
12366		  
12367		  slider_control_swipe:true,					//true,false - enable swiping control
12368		  slider_control_zoom:true,						//true, false - enable zooming control
12369		  slider_zoom_mousewheel: true,					//enable zoom on mousewheel
12370		  slider_vertical_scroll_ondrag: false,			//vertical scroll on slider area drag					  
12371		  slider_loader_type: 1,						//shape of the loader (1-7)
12372		  slider_loader_color:"white",					//color of the loader: (black , white)
12373		  slider_enable_links: true,					//enable slide as link functionality
12374		  slider_links_newpage: false,					//open the slide link in new page
12375		  
12376		  slider_enable_bullets: false,					//enable the bullets onslider element
12377		  slider_bullets_skin: "",						//skin of the bullets, if empty inherit from gallery skin
12378		  slider_bullets_space_between: -1,				//set the space between bullets. If -1 then will be set default space from the skins
12379		  slider_bullets_align_hor:"center",			//left, center, right - bullets horizontal align
12380		  slider_bullets_align_vert:"bottom",			//top, middle, bottom - bullets vertical algin
12381		  slider_bullets_offset_hor:0,					//bullets horizontal offset 
12382		  slider_bullets_offset_vert:10,				//bullets vertical offset
12383		  
12384		  slider_enable_arrows: true,					//enable arrows onslider element
12385		  slider_arrows_skin: "",						//skin of the slider arrows, if empty inherit from gallery skin
12386		  
12387		  slider_arrow_left_align_hor:"left",	  		//left, center, right - left arrow horizonal align
12388		  slider_arrow_left_align_vert:"middle", 		//top, middle, bottom - left arrow vertical align
12389		  slider_arrow_left_offset_hor:20,		  		//left arrow horizontal offset
12390		  slider_arrow_left_offset_vert:0,		  		//left arrow vertical offset
12391		  
12392		  slider_arrow_right_align_hor:"right",   		//left, center, right - right arrow horizontal algin
12393		  slider_arrow_right_align_vert:"middle", 		//top, middle, bottom - right arrow vertical align
12394		  slider_arrow_right_offset_hor:20,	   			//right arrow horizontal offset 
12395		  slider_arrow_right_offset_vert:0,	   			//right arrow vertical offset
12396		  
12397		  slider_enable_progress_indicator: true,		 //enable progress indicator element
12398		  slider_progress_indicator_type: "pie",		 //pie, pie2, bar (if pie not supported, it will switch to bar automatically)
12399		  slider_progress_indicator_align_hor:"right",   //left, center, right - progress indicator horizontal align
12400		  slider_progress_indicator_align_vert:"top",    //top, middle, bottom - progress indicator vertical align
12401		  slider_progress_indicator_offset_hor:10,	     //progress indicator horizontal offset 
12402		  slider_progress_indicator_offset_vert:10,	     //progress indicator vertical offset
12403		  
12404		  slider_enable_play_button: true,				 //true,false - enable play / pause button onslider element
12405		  slider_play_button_skin: "",					 //skin of the slider play button, if empty inherit from gallery skin
12406		  slider_play_button_align_hor:"left",    		 //left, center, right - play button horizontal align
12407		  slider_play_button_align_vert:"top",     		 //top, middle, bottom - play button vertical align
12408		  slider_play_button_offset_hor:40,	       		 //play button horizontal offset 
12409		  slider_play_button_offset_vert:8,	   			 //play button vertical offset
12410		  slider_play_button_mobilehide:false,		 	 //hide the play button on mobile
12411		  
12412		  slider_enable_fullscreen_button: true,		 //true,false - enable fullscreen button onslider element
12413		  slider_fullscreen_button_skin: "",			 //skin of the slider fullscreen button, if empty inherit from gallery skin
12414		  slider_fullscreen_button_align_hor:"left",     //left, center, right	- fullscreen button horizonatal align
12415		  slider_fullscreen_button_align_vert:"top",     //top, middle, bottom - fullscreen button vertical align
12416		  slider_fullscreen_button_offset_hor:11,	     //fullscreen button horizontal offset 
12417		  slider_fullscreen_button_offset_vert:9,	   	 //fullscreen button vertical offset
12418		  slider_fullscreen_button_mobilehide:false,	 //hide the button on mobile
12419		  
12420		  slider_enable_zoom_panel: true,				 //true,false - enable the zoom buttons, works together with zoom control.
12421		  slider_zoompanel_skin: "",					 //skin of the slider zoom panel, if empty inherit from gallery skin		  
12422		  slider_zoompanel_align_hor:"left",    		 //left, center, right - zoom panel horizontal align
12423		  slider_zoompanel_align_vert:"top",     	 	 //top, middle, bottom - zoom panel vertical align
12424		  slider_zoompanel_offset_hor:12,	       		 //zoom panel horizontal offset 
12425		  slider_zoompanel_offset_vert:92,	   			 //zoom panel vertical offset
12426		  slider_zoompanel_mobilehide:false,		     //hide the zoom panel on mobile
12427		  
12428		  slider_controls_always_on: false,				//true,false - controls are always on, false - show only on mouseover
12429		  slider_controls_appear_ontap: true,			//true,false - appear controls on tap event on touch devices
12430		  slider_controls_appear_duration: 300,			//the duration of appearing controls
12431		  
12432		  slider_enable_text_panel: true,				//true,false - enable the text panel
12433		  slider_textpanel_always_on: true,				//true,false - text panel are always on, false - show only on mouseover
12434		  
12435		  slider_videoplay_button_type: "square"		//square, round - the videoplay button type, square or round	
12436	};
12437	
12438	
12439	//default options for bar progress incicator
12440	var g_defaultsProgressBar = {
12441		  slider_progress_indicator_align_hor:"left",    	//left, center, right
12442		  slider_progress_indicator_align_vert:"bottom",    //top, middle, bottom
12443		  slider_progress_indicator_offset_hor:0,	       	//horizontal offset 
12444		  slider_progress_indicator_offset_vert:0	   		//vertical offset
12445	};
12446	
12447	var g_temp = {
12448		isRunOnce: false,
12449		isTextPanelSaparateHover: false,					//if the panel need to be appeared without the controls object on mouseover
12450		numPrev:1,
12451		numCurrent:2,
12452		numNext: 3,
12453		isControlsVisible: true,
12454		currentControlsMode: "image"
12455	};
12456	
12457	function __________GENERAL___________(){};
12458	
12459	
12460	/**
12461	 * init the slider
12462	 */
12463	function initSlider(objGallery, objOptions, optionsPrefix){
12464		g_gallery = objGallery;
12465				
12466		//change options by prefix
12467		if(optionsPrefix){
12468			g_optionsPrefix = optionsPrefix;
12469			objOptions = g_functions.convertCustomPrefixOptions(objOptions, g_optionsPrefix, "slider");
12470		}
12471		
12472		g_objGallery = jQuery(objGallery);
12473		
12474		var objects = g_gallery.getObjects();		
12475		g_objWrapper = objects.g_objWrapper;
12476		g_objThumbs = objects.g_objThumbs;
12477		
12478		//set progress indicator bar defaults if type bar
12479		if(objOptions.hasOwnProperty("slider_progress_indicator_type"))
12480			g_options.slider_progress_indicator_type = objOptions.slider_progress_indicator_type;
12481		
12482		if(g_options.slider_progress_indicator_type == "bar"){
12483			g_options = jQuery.extend(g_options, g_defaultsProgressBar);
12484		}
12485				
12486		if(objOptions)
12487			t.setOptions(objOptions);
12488		
12489		processOptions();
12490		
12491		//init bullets:
12492		if(g_options.slider_enable_bullets == true){
12493			g_objBullets = new UGBullets();
12494			var bulletsOptions = {
12495					bullets_skin: g_options.slider_bullets_skin,
12496					bullets_space_between: g_options.slider_bullets_space_between
12497			}
12498			g_objBullets.init(g_gallery, bulletsOptions);
12499		}
12500		
12501		//init text panel
12502		if(g_options.slider_enable_text_panel){
12503			g_objTextPanel = new UGTextPanel();
12504			g_objTextPanel.init(g_gallery, g_options, "slider");
12505		}
12506		
12507		if(g_options.slider_enable_zoom_panel){
12508			g_objZoomPanel = new UGZoomButtonsPanel();
12509			g_objZoomPanel.init(t, g_options);
12510		}
12511		
12512		var galleryID = g_gallery.getGalleryID();
12513		
12514		//init video player
12515		g_objVideoPlayer.init(g_options, false, galleryID);		
12516	}
12517	
12518	
12519	/**
12520	 * run the slider functionality
12521	 */
12522	function runSlider(){
12523		
12524		if(g_temp.isRunOnce == true)
12525			return(false);
12526		
12527		g_temp.isRunOnce = true;
12528		
12529		//set background color
12530	   if(g_options.slider_background_color){	   		
12531		   var bgColor = g_options.slider_background_color;
12532		   
12533		   if(g_options.slider_background_opacity != 1)
12534			   bgColor = g_functions.convertHexToRGB(bgColor, g_options.slider_background_opacity);
12535		   
12536		   g_objSlider.css("background-color", bgColor);
12537	   
12538	   }else if(g_options.slider_background_opacity != 1){	//set opacity with default color
12539		
12540		   bgColor = g_functions.convertHexToRGB("#000000", g_options.slider_background_opacity);
12541		   g_objSlider.css("background-color", bgColor);
12542	  
12543	   }
12544	   
12545		//init touch slider control
12546		if(g_options.slider_control_swipe == true){
12547			g_objTouchSlider = new UGTouchSliderControl();
12548			g_objTouchSlider.init(t, g_options);
12549		}
12550
12551		//init zoom slider control
12552		if(g_options.slider_control_zoom == true){
12553			g_objZoomSlider = new UGZoomSliderControl();
12554			g_objZoomSlider.init(t, g_options);
12555		}
12556		
12557		//run the text panel
12558		if(g_objTextPanel)
12559			g_objTextPanel.run();
12560		
12561		initEvents();		
12562	}
12563	
12564	
12565	/**
12566	 * process the options
12567	 */
12568	function processOptions(){
12569		var galleryOptions = g_gallery.getOptions();
12570		
12571		//set skins:
12572		var globalSkin = galleryOptions.gallery_skin;
12573		
12574		if(g_options.slider_bullets_skin == "")
12575			g_options.slider_bullets_skin = globalSkin;
12576		
12577		if(g_options.slider_arrows_skin == "")
12578			g_options.slider_arrows_skin = globalSkin;
12579		
12580		if(g_options.slider_zoompanel_skin == "")
12581			g_options.slider_zoompanel_skin = globalSkin;
12582		
12583		if(g_options.slider_play_button_skin == "")
12584			g_options.slider_play_button_skin = globalSkin;
12585		
12586		if(g_options.slider_fullscreen_button_skin == "")
12587			g_options.slider_fullscreen_button_skin = globalSkin;
12588		
12589		g_options.video_enable_closebutton = g_options.slider_video_enable_closebutton;
12590		
12591		//set mousewheel option depends on the gallery option
12592		if(galleryOptions.gallery_mousewheel_role != "zoom")
12593			g_options.slider_zoom_mousewheel = false;
12594	
12595	}
12596	
12597	
12598	/**
12599	 * 
12600	 * get html slide
12601	 */
12602	function getHtmlSlide(loaderClass, numSlide){
12603		
12604		var classVideoplay = "ug-type-square";
12605		if(g_options.slider_videoplay_button_type == "round")
12606			classVideoplay = "ug-type-round";
12607		
12608		var html = "";
12609		html += "<div class='ug-slide-wrapper ug-slide"+numSlide+"'>";
12610		html += "<div class='ug-item-wrapper'></div>";
12611		html += "<div class='ug-slider-preloader "+loaderClass+"'></div>";
12612		html += "<div class='ug-button-videoplay "+classVideoplay+"' style='display:none'></div>";
12613		html += "</div>";
12614		
12615		return(html);
12616	}
12617	
12618	
12619	/**
12620	 * set the slider html
12621	 */
12622	function setHtmlSlider(objParent){
12623		
12624		if(objParent)
12625			g_objWrapper = objParent;
12626		
12627		//get if the slide has controls
12628		var loaderClass = getLoaderClass();
12629		var galleryOptions = g_gallery.getOptions();
12630		
12631		var html = "<div class='ug-slider-wrapper'>";
12632		
12633		html += "<div class='ug-slider-inner'>";
12634		html += getHtmlSlide(loaderClass,1);
12635		html += getHtmlSlide(loaderClass,2);
12636		html += getHtmlSlide(loaderClass,3);
12637				
12638		html += "</div>";	//end inner
12639		
12640		//----------------
12641				
12642		//add arrows
12643		if(g_options.slider_enable_arrows == true){
12644			html += "<div class='ug-slider-control ug-arrow-left ug-skin-"+g_options.slider_arrows_skin+"'></div>";
12645			html += "<div class='ug-slider-control ug-arrow-right ug-skin-"+g_options.slider_arrows_skin+"'></div>";
12646		}
12647		
12648		//add play button
12649		if(g_options.slider_enable_play_button == true){
12650			html += "<div class='ug-slider-control ug-button-play ug-skin-"+g_options.slider_play_button_skin+"'></div>";
12651		}
12652		
12653		//add fullscreen button
12654		if(g_options.slider_enable_fullscreen_button == true){
12655			html += "<div class='ug-slider-control ug-button-fullscreen ug-skin-"+g_options.slider_fullscreen_button_skin+"'></div>";
12656		}
12657		
12658		
12659		html +=	"</div>";	//end slider
12660		
12661		
12662		g_objWrapper.append(html);
12663		
12664		//----------------
12665		
12666		//set objects
12667		g_objSlider = g_objWrapper.children(".ug-slider-wrapper");
12668		g_objInner = g_objSlider.children(".ug-slider-inner");
12669		
12670		
12671		g_objSlide1 = g_objInner.children(".ug-slide1");
12672		g_objSlide2 = g_objInner.children(".ug-slide2");
12673		g_objSlide3 = g_objInner.children(".ug-slide3");
12674		
12675		//set slides data
12676		g_objSlide1.data("slidenum",1);
12677		g_objSlide2.data("slidenum",2);
12678		g_objSlide3.data("slidenum",3);
12679				
12680		//add bullets
12681		if(g_objBullets)
12682			g_objBullets.appendHTML(g_objSlider);
12683		
12684		//----------------
12685		
12686		//get arrows object
12687		if(g_options.slider_enable_arrows == true){
12688			g_objArrowLeft = g_objSlider.children(".ug-arrow-left");
12689			g_objArrowRight = g_objSlider.children(".ug-arrow-right");
12690		}
12691				
12692		//get play button
12693		if(g_options.slider_enable_play_button == true){
12694			g_objButtonPlay = g_objSlider.children(".ug-button-play");
12695		}
12696		
12697		//get fullscreen button
12698		if(g_options.slider_enable_fullscreen_button == true){
12699			g_objButtonFullscreen = g_objSlider.children(".ug-button-fullscreen");
12700		}
12701		
12702		
12703		//----------------
12704		
12705		//add progress indicator
12706		if(g_options.slider_enable_progress_indicator == true){
12707			
12708			g_objProgress = g_functions.initProgressIndicator(g_options.slider_progress_indicator_type, g_options, g_objSlider);
12709			
12710			var finalType = g_objProgress.getType();
12711			
12712			//change options in case of type change
12713			if(finalType == "bar" && g_options.slider_progress_indicator_type == "pie"){
12714				g_options.slider_progress_indicator_type = "bar";
12715				g_options = jQuery.extend(g_options, g_defaultsProgressBar);
12716			}	
12717			
12718			g_gallery.setProgressIndicator(g_objProgress);
12719		}
12720		
12721		//----------------
12722		
12723		//add text panel (hidden)
12724		if(g_options.slider_enable_text_panel == true){
12725			
12726				g_objTextPanel.appendHTML(g_objSlider);
12727								
12728				//hide panel saparatelly from the controls object
12729				if(g_options.slider_textpanel_always_on == false){
12730					
12731					//hide the panel
12732					var panelElement = g_objTextPanel.getElement();
12733					panelElement.hide().data("isHidden", true);
12734	
12735					g_temp.isTextPanelSaparateHover = true;
12736					
12737				}
12738			
12739		}
12740			
12741		//----------------
12742		
12743		//add zoom buttons panel:
12744		if(g_options.slider_enable_zoom_panel == true){
12745			g_objZoomPanel.appendHTML(g_objSlider);
12746		}
12747	
12748		
12749		//add video player
12750		g_objVideoPlayer.setHtml(g_objInner);
12751	}
12752	
12753	
12754	/**
12755	 * position elements that related to slide
12756	 */
12757	function positionSlideElements(objSlide){
12758		
12759		//position preloader
12760		var objPreloader = getSlidePreloader(objSlide);
12761		g_functions.placeElementInParentCenter(objPreloader);
12762		
12763		//position video play button
12764		var objVideoPlayButton = getSlideVideoPlayButton(objSlide);
12765		g_functions.placeElementInParentCenter(objVideoPlayButton);		
12766	}
12767	
12768	
12769	/**
12770	 * position elements
12771	 */
12772	function positionElements(){
12773		
12774		//place bullets
12775		if(g_objBullets){
12776			objBullets = g_objBullets.getElement();
12777			
12778			//strange bug fix (bullets width: 20) by double placing
12779			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);
12780			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);
12781			
12782		}
12783		
12784		//place arrows
12785		if(g_options.slider_enable_arrows == true){
12786			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);
12787			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);
12788		}
12789		
12790		//hide controls
12791		if(g_options.slider_controls_always_on == false)
12792			hideControls(true);
12793		
12794		//place progress indicator
12795		if(g_objProgress){
12796			
12797			var objProgressElement = g_objProgress.getElement();
12798			
12799			if(g_options.slider_progress_indicator_type == "bar"){
12800				var sliderWidth = g_objSlider.width();				
12801				g_objProgress.setSize(sliderWidth);
12802				g_functions.placeElement(objProgressElement, "left", g_options.slider_progress_indicator_align_vert, 0, g_options.slider_progress_indicator_offset_vert);				
12803				
12804			}else{
12805				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);				
12806				
12807			}			
12808		}
12809				
12810		//position text panel
12811		if(g_objTextPanel)
12812			g_objTextPanel.positionPanel();
12813		
12814		//position controls elements
12815		placeControlsElements();
12816		
12817		//place slide elements
12818		positionSlideElements(g_objSlide1);
12819		positionSlideElements(g_objSlide2);
12820		positionSlideElements(g_objSlide3);
12821		
12822		checkMobileModify();
12823		
12824	}
12825	
12826	
12827	/**
12828	 * place elements that located on "controls" div
12829	 */
12830	function placeControlsElements(){
12831		
12832		if(g_objButtonPlay)			
12833			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);			
12834		
12835		//position fullscreen button
12836		if(g_objButtonFullscreen)			
12837			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);
12838		
12839		//position zoom panel
12840		if(g_objZoomPanel){
12841			var zoomPanelElement = g_objZoomPanel.getElement();
12842			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);
12843		}
12844	}
12845	
12846	
12847		
12848	/**
12849	 * position slides by their order
12850	 */
12851	function positionSlides(){
12852		
12853		var slides = t.getSlidesReference();
12854		var posX = 0, posY = 0, innerWidth;
12855		var posXPrev=0, posXCurrent = 0, posXNext, nextHasItem, prevHasItem;
12856				
12857		nextHasItem = t.isSlideHasItem(slides.objNextSlide);
12858		prevHasItem = t.isSlideHasItem(slides.objPrevSlide);
12859		
12860		if(prevHasItem){
12861			posXCurrent = slides.objPrevSlide.outerWidth();
12862			slides.objPrevSlide.css("z-index",1);
12863		}else
12864			slides.objPrevSlide.hide();			
12865		
12866		posXNext = posXCurrent + slides.objCurrentSlide.outerWidth();
12867		
12868		innerWidth = posXNext;
12869		if(nextHasItem){
12870			innerWidth = posXNext + slides.objNextSlide.outerWidth();
12871			slides.objPrevSlide.css("z-index",2);		
12872		}else
12873			slides.objNextSlide.hide();
12874		
12875		slides.objCurrentSlide.css("z-index",3);
12876		
12877		//set inner size and position
12878		g_functions.placeElement(slides.objCurrentSlide, posXCurrent, posY);		
12879		g_objInner.css({"left":-posXCurrent+"px", width:innerWidth+"px"});
12880
12881		//position prev
12882		if(prevHasItem){
12883			g_functions.placeElement(slides.objPrevSlide, posXPrev, posY);
12884			g_functions.showElement(slides.objPrevSlide);
12885		}
12886		
12887		if(nextHasItem){
12888			g_functions.showElement(slides.objNextSlide);
12889			g_functions.placeElement(slides.objNextSlide, posXNext, posY);
12890		}
12891		
12892	}
12893	
12894	
12895	
12896	/**
12897	 * resize the slide image inside item
12898	 */
12899	function resizeSlideItem(objSlide){
12900		var index = objSlide.data("index");
12901		if(index === undefined || index == null)
12902			return(false);
12903		
12904		var objItem = g_gallery.getItem(index);
12905		
12906		if(!objItem)
12907			return(false);
12908		
12909		setItemToSlide(objSlide, objItem);
12910	}
12911	
12912	
12913	/**
12914	 * show the preloader
12915	 * show the index, so only the current index load will hide.
12916	 */	
12917	function showPreloader(objPreloader){
12918		
12919		objPreloader.stop(true).show(100);
12920	
12921	}
12922	
12923	/**
12924	 * hide the preloader
12925	 */
12926	function hidePreloader(objPreloader){
12927		
12928		objPreloader.stop(true).hide(100);
12929	}
12930	
12931	/**
12932	 * get proper image border width
12933	 */
12934	function getImageBorderWidth(objImage, imageData){
12935		
12936		var borderWidth = g_options.slider_image_border_width;
12937		
12938		if(borderWidth <= 10)
12939			return(borderWidth);
12940
12941		//set image size
12942		var imageSize = g_functions.getElementSize(objImage);
12943		var imageWidth = imageSize.width;
12944		var imageHeight = imageSize.height;
12945		
12946		if(imageData){
12947			if(imageData.hasOwnProperty("imageWidth"))
12948				imageWidth = imageData.imageWidth;
12949			
12950			if(imageData.hasOwnProperty("imageHeight"))
12951				imageHeight = imageData.imageHeight;
12952			
12953		}
12954		
12955		if(imageWidth <= 0)
12956			return(borderWidth);
12957		
12958		//take the less size
12959		var totalSize = (imageWidth < imageHeight)?imageWidth:imageHeight;
12960		var borderSize = borderWidth * 2;
12961		
12962		var borderRatio = borderSize / totalSize;
12963		
12964		if(borderRatio < g_options.slider_image_border_maxratio)
12965			return(borderWidth);
12966		
12967		//change border width		
12968		var borderWidth = (totalSize * g_options.slider_image_border_maxratio)/2; 
12969		
12970		borderWidth = Math.round(borderWidth);
12971		
12972		return(borderWidth);
12973		
12974	}
12975	
12976	
12977	/**
12978	 * set slider image css design according the settings
12979	 */
12980	function setImageDesign(objImage, slideType, imageData){
12981		
12982		var css = {};
12983		if(g_options.slider_image_border == true){
12984			css["border-style"] = "solid";
12985			
12986			var borderWidth = getImageBorderWidth(objImage, imageData);
12987			
12988			css["border-width"] = borderWidth+"px";
12989			css["border-color"] = g_options.slider_image_border_color;
12990			css["border-radius"] = g_options.slider_image_border_radius;
12991		}
12992		
12993		if(slideType != "image" && g_options.slider_video_constantsize == true)
12994			css["background-color"] = "#000000";
12995		
12996		if(g_options.slider_image_shadow == true){
12997			css["box-shadow"] = "3px 3px 10px 0px #353535";
12998		}
12999		
13000		objImage.css(css);
13001	}
13002	
13003	
13004	/**
13005	 * scale image constant size (for video items)
13006	 */
13007	function scaleImageConstantSize(objImage, objItem){
13008		
13009		var constantWidth = g_options.slider_video_constantsize_width;
13010		var constantHeight = g_options.slider_video_constantsize_height;
13011		var scaleMode = g_options.slider_video_constantsize_scalemode;
13012		
13013		var objSize = g_functions.scaleImageExactSizeInParent(objImage, objItem.imageWidth, objItem.imageHeight, constantWidth, constantHeight, scaleMode);
13014		
13015		
13016		return(objSize);
13017	}
13018
13019	
13020	/**
13021	 * 
13022	 * set item to slide
13023	 */
13024	function setImageToSlide(objSlide, objItem, isForce){
13025		
13026		var objItemWrapper = objSlide.children(".ug-item-wrapper");
13027		
13028		var objPreloader = getSlidePreloader(objSlide);
13029		
13030		if(typeof objItem.urlImage == "undefined" || objItem.urlImage == "")
13031			throw new Error("The slide don't have big image defined ( data-image='imageurl' ). Please check gallery items.", "showbig");
13032		
13033		var urlImage = objItem.urlImage;
13034		
13035		var currentImage = objSlide.data("urlImage");
13036				
13037		objSlide.data("urlImage",urlImage);
13038		
13039		var scaleMode = t.getScaleMode(objSlide);
13040		
13041		var slideType = t.getSlideType(objSlide);
13042		
13043		objPadding = t.getObjImagePadding();
13044		
13045		
13046		if(currentImage == urlImage && isForce !== true){
13047			
13048			var objImage = objItemWrapper.children("img");
13049						
13050			if(objItem.imageWidth == 0 || objItem.imageHeight == 0){
13051				g_gallery.checkFillImageSize(objImage, objItem);
13052			}
13053			
13054			var objImageData = {};
13055			
13056			if(slideType != "image" && g_options.slider_video_constantsize == true){
13057				objImageData = scaleImageConstantSize(objImage, objItem);
13058			}
13059			else{
13060				objImageData = g_functions.scaleImageFitParent(objImage, objItem.imageWidth, objItem.imageHeight, scaleMode, objPadding);
13061			}
13062			
13063			setImageDesign(objImage, slideType, objImageData);
13064			g_objThis.trigger(t.events.AFTER_PUT_IMAGE, objSlide);
13065			
13066		}
13067		else{		//place the image inside parent first time
13068			
13069			objImage = g_functions.placeImageInsideParent(urlImage, objItemWrapper, objItem.imageWidth, objItem.imageHeight, scaleMode, objPadding);
13070			
13071			//set image loaded on load:
13072			if(objItem.isBigImageLoaded == true){
13073				objImage.fadeTo(0,1);
13074				hidePreloader(objPreloader);
13075				
13076				if(slideType != "image" && g_options.slider_video_constantsize == true)
13077					var objImageData = scaleImageConstantSize(objImage, objItem);
13078				else
13079					var objImageData = g_functions.getImageInsideParentData(objItemWrapper, objItem.imageWidth, objItem.imageHeight, scaleMode, objPadding);
13080				
13081				//set missing css width
13082				objImage.css("width",objImageData.imageWidth+"px");
13083						
13084				setImageDesign(objImage, slideType, objImageData);
13085				
13086				g_objThis.trigger(t.events.AFTER_PUT_IMAGE, objSlide);
13087			}
13088			else{		//if the image not loaded, load the image and show it after.
13089				objImage.fadeTo(0,0);
13090				showPreloader(objPreloader);
13091				objSlide.data("isLoading", true);
13092				
13093				if(t.isSlideCurrent(objSlide))
13094					g_objThis.trigger(t.events.CURRENTSLIDE_LOAD_START);
13095				
13096				objImage.data("itemIndex", objItem.index);
13097				objImage.on("load",function(){
13098					
13099					//place the image normally with coordinates
13100					var objImage = jQuery(this);
13101					var itemIndex = objImage.data("itemIndex");
13102					
13103					objImage.fadeTo(0,1);
13104					
13105					//get and hide preloader
13106					var objSlide = objImage.parent().parent();
13107					var slideType = t.getSlideType(objSlide);
13108					var objPreloader = getSlidePreloader(objSlide);
13109					var objPadding = t.getObjImagePadding();
13110					var scaleMode = t.getScaleMode(objSlide);
13111					
13112					hidePreloader(objPreloader);
13113					objSlide.data("isLoading", false);
13114					
13115					if(t.isSlideCurrent(objSlide))
13116						g_objThis.trigger(t.events.CURRENTSLIDE_LOAD_END);
13117					
13118					g_gallery.onItemBigImageLoaded(null, objImage);
13119					
13120					var objItem = g_gallery.getItem(itemIndex);
13121					
13122					var objImageData = {};
13123					
13124					if(slideType != "image" && g_options.slider_video_constantsize == true)
13125						scaleImageConstantSize(objImage, objItem);
13126					else{
13127						objImageData = g_functions.scaleImageFitParent(objImage, objItem.imageWidth, objItem.imageHeight, scaleMode, objPadding);
13128					}
13129					
13130					objImage.fadeTo(0,1);
13131					
13132					setImageDesign(objImage, slideType, objImageData);
13133					
13134					g_objThis.trigger(t.events.AFTER_PUT_IMAGE, objSlide);
13135				});
13136			}
13137			
13138		}
13139		
13140		
13141	}
13142	
13143		
13144	
13145	/**
13146	 * set slider image by url
13147	 * if item not set, get current slide item
13148	 */
13149	function setItemToSlide(objSlide, objItem){
13150		
13151		try{
13152
13153			var objItemWrapper = objSlide.children(".ug-item-wrapper");
13154					
13155			//if the item is empty, remove the image from slide
13156			if(objItem == null){
13157				objItemWrapper.html("");
13158				objSlide.removeData("index");
13159				objSlide.removeData("type");
13160				objSlide.removeData("urlImage");
13161				return(false);
13162			}
13163			
13164			var currentIndex = objSlide.data("index");
13165			
13166			objSlide.data("index",objItem.index);
13167			objSlide.data("type", objItem.type);
13168			
13169			//set link class
13170			if(g_options.slider_enable_links == true && objItem.type == "image"){
13171				
13172				if(objItem.link)
13173					objSlide.addClass("ug-slide-clickable");
13174				else
13175					objSlide.removeClass("ug-slide-clickable");
13176			}
13177			
13178			setImageToSlide(objSlide, objItem);
13179			
13180			//show type related elements
13181			var objVideoPlayButton = getSlideVideoPlayButton(objSlide);
13182			switch(objItem.type){
13183				case "image":
13184					objVideoPlayButton.hide();
13185				break;
13186				default:		//video
13187					objVideoPlayButton.show();					
13188				break;
13189			}
13190			
13191		}catch(error){
13192			
13193			if(typeof error.fileName != "undefined" && error.fileName == "showbig")
13194				g_gallery.showErrorMessageReplaceGallery(error.message);
13195			
13196			objItemWrapper.html("");
13197			throw new Error(error);
13198			return(true);
13199		}
13200		
13201	}	
13202	
13203	
13204	
13205	/**
13206	 * hide the panel
13207	 */
13208	function hideTextPanel(){
13209		
13210		if(!g_objTextPanel)
13211			return(false);
13212		
13213		if(isTextPanelHidden() == true)
13214			return(false);
13215		
13216		var panelElement = g_objTextPanel.getElement();
13217	
13218		var animationTime = 0;
13219		if(g_temp.isTextPanelSaparateHover == true || g_options.slider_textpanel_always_on == true){
13220			animationTime = g_options.slider_controls_appear_duration;
13221		}
13222		
13223		panelElement.stop().fadeTo(animationTime, 0);
13224		
13225		panelElement.data("isHidden", true);
13226	}
13227	
13228	
13229	/**
13230	 * show the text panel
13231	 */
13232	function showTextPanel(){
13233		
13234		if(!g_objTextPanel)
13235			return(false);
13236		
13237		if(isTextPanelHidden() == false)
13238			return(false);
13239		
13240		var panelElement = g_objTextPanel.getElement();
13241		
13242		var animationTime = 0;
13243		
13244		if(g_temp.isTextPanelSaparateHover == true || g_options.slider_textpanel_always_on == true){
13245			
13246			panelElement.show();
13247			g_objTextPanel.positionElements();
13248			
13249			animationTime = g_options.slider_controls_appear_duration;
13250		}
13251		
13252		panelElement.stop().show().fadeTo(animationTime,1);
13253		
13254		panelElement.data("isHidden", false);
13255				
13256	}
13257	
13258	
13259	/**
13260	 * check if the text panel is hidden or not
13261	 */
13262	function isTextPanelHidden(){
13263
13264		var panelElement = g_objTextPanel.getElement();
13265
13266		var isHidden = panelElement.data("isHidden");
13267		if(isHidden === false)
13268			return(false);
13269		
13270		return(true);		
13271	}	
13272	
13273	
13274	/**
13275	 * validate that the slide is certain type, if not, throw error
13276	 */
13277	function validateSlideType(type, objSlide){
13278		if(objSlide == undefined)
13279			var objSlide = t.getCurrentSlide();
13280		
13281		var slideType = t.getSlideType(objSlide);
13282				
13283		if(slideType != type){
13284			throw new Error("Wrong slide type: "+ slideType +", should be: "+type);
13285			return(false);
13286		}
13287		
13288		return(true);
13289	}
13290	
13291	function __________VIDEO_PLAYER_______(){};
13292
13293	
13294	
13295	/**
13296	 * set video player position
13297	 */
13298	function setVideoPlayerPosition(){
13299		
13300		var objCurrentSlide = t.getCurrentSlide();
13301		var objImage = t.getSlideImage(objCurrentSlide);
13302		
13303		var slideSize = g_functions.getElementSize(objCurrentSlide);
13304		var left = slideSize.left;
13305		var top = slideSize.top;
13306				
13307		//set by image position
13308		if(g_options.slider_video_constantsize == true){
13309			
13310			var imageSize = g_functions.getElementSize(objImage);
13311			left += imageSize.left;
13312			top += imageSize.top;
13313			
13314		}else{	//set video padding
13315			
13316			left += g_options.slider_video_padding_left;
13317			top += g_options.slider_video_padding_top;
13318		
13319		}
13320		
13321		g_objVideoPlayer.setPosition(left, top);
13322	}
13323	
13324	
13325	/**
13326	 * set video player constant size
13327	 */
13328	function setVideoPlayerConstantSize(){
13329		
13330		var videoWidth = g_options.slider_video_constantsize_width;
13331		var videoHeight = g_options.slider_video_constantsize_height;
13332		
13333		g_objVideoPlayer.setSize(videoWidth, videoHeight);
13334		
13335		//set video design
13336		var videoElement = g_objVideoPlayer.getObject();
13337		
13338		setImageDesign(videoElement, "video");
13339	}
13340	
13341	
13342	function __________TRANSITION_______(){};
13343
13344	
13345	
13346	/**
13347	 * do the transition between the current and the next
13348	 */
13349	function doTransition(direction, objItem, forceTransition){
13350		
13351		g_objThis.trigger(t.events.TRANSITION_START);
13352		
13353		var transition = g_options.slider_transition;
13354		if(forceTransition)
13355			transition = forceTransition;
13356
13357		//stop current slide action
13358		t.stopSlideAction(null, true);
13359		
13360		switch(transition){
13361			default:
13362			case "fade":
13363				transitionFade(objItem);
13364			break;
13365			case "slide":				
13366				transitionSlide(direction, objItem);
13367			break;
13368			case "lightbox_open":		//fade transition without animation
13369				transitionFade(objItem, false, true);
13370			break;
13371		}
13372		
13373	}
13374
13375	
13376	/**
13377	 * switch slide numbers after transition (by direction)
13378	 * 
13379	 */
13380	this.switchSlideNums = function(direction){
13381		
13382		//trigger item changed effect
13383		g_objThis.trigger(t.events.BEFORE_SWITCH_SLIDES);
13384		
13385		switch(direction){
13386			case "left":
13387				var currentNum = g_temp.numCurrent;
13388				g_temp.numCurrent = g_temp.numNext;
13389				g_temp.numNext = g_temp.numPrev;
13390				g_temp.numPrev = currentNum;
13391			break;
13392			case "right":
13393				var currentNum = g_temp.numCurrent;
13394				g_temp.numCurrent = g_temp.numPrev;
13395				g_temp.numPrev = g_temp.numNext;
13396				g_temp.numNext = currentNum;				
13397			break;
13398			default:
13399				throw new Error("wrong direction: "+ direction);
13400			break;
13401		}
13402		
13403		//trace(g_temp.numCurrent);
13404		
13405		//trigger item changed effect
13406		g_objThis.trigger(t.events.ITEM_CHANGED);
13407	}
13408	
13409	
13410	/**
13411	 * do slide transition
13412	 */
13413	function transitionSlide(direction, objItem){
13414		
13415		var animating = t.isAnimating();
13416
13417		if(animating == true){
13418			g_temp.itemWaiting = objItem;
13419			return(true);
13420		}
13421		
13422		//always clear next item on transition start
13423		// next item can be only in the middle of the transition.
13424		if(g_temp.itemWaiting != null)
13425			g_temp.itemWaiting = null;
13426		
13427		var slides = t.getSlidesReference();
13428		
13429		
13430		switch(direction){
13431			case "right":	//change to prev item
13432				setItemToSlide(slides.objPrevSlide, objItem);
13433				positionSlides();
13434				
13435				var posPrev = g_functions.getElementSize(slides.objPrevSlide);
13436				var destX = -posPrev.left;
13437				
13438				t.switchSlideNums("right");
13439				
13440			break;	
13441			case "left":		//change to next item
13442				setItemToSlide(slides.objNextSlide, objItem);
13443				positionSlides();
13444				
13445				var posNext = g_functions.getElementSize(slides.objNextSlide);
13446				var destX = -posNext.left;
13447				
13448				t.switchSlideNums("left");
13449				
13450			break;
13451			default:
13452				throw new Error("wrong direction: "+direction);
13453			break;
13454		}
13455				
13456		var transSpeed = g_options.slider_transition_speed;
13457		var transEasing = g_options.slider_transition_easing;
13458
13459		
13460		var animateParams = {
13461				duration: transSpeed,
13462				easing: transEasing,
13463				queue: false,
13464				always:function(){
13465						
13466						t.stopSlideAction();
13467						g_objVideoPlayer.hide();
13468						
13469						//transit next item if waiting
13470						if(g_temp.itemWaiting != null){
13471							var direction = getSlideDirection(g_temp.itemWaiting);
13472							transitionSlide(direction, g_temp.itemWaiting);
13473						}else{
13474							//if no item waiting, please neighbour items in places
13475							t.placeNabourItems();
13476							g_objThis.trigger(t.events.TRANSITION_END);
13477						}
13478					
13479				}
13480		};
13481		
13482		
13483		g_objInner.animate({left:destX+"px"}, animateParams);
13484			
13485	}
13486	
13487	
13488	/**
13489	 * 
13490	 * animate opacity in and out
13491	 */
13492	function animateOpacity(objItem, opacity, completeFunction){
13493		
13494		if(completeFunction)
13495			objItem.fadeTo(g_options.slider_transition_speed, opacity, completeFunction);
13496		else
13497			objItem.fadeTo(g_options.slider_transition_speed, opacity);
13498	}
13499	
13500	
13501	/**
13502	 * do fade transition
13503	 */
13504	function transitionFade(objItem, noAnimation, noHidePlayer){
13505		
13506		if(!noAnimation)
13507			var noAnimation = false;
13508		
13509		var slides = t.getSlidesReference();
13510		 
13511		setItemToSlide(slides.objNextSlide, objItem);
13512		
13513		var objCurrentPos = g_functions.getElementSize(slides.objCurrentSlide);
13514				
13515		g_functions.placeElement(slides.objNextSlide,objCurrentPos.left,objCurrentPos.top);
13516		
13517		//switch slide nums
13518		var currentNum = g_temp.numCurrent;
13519		g_temp.numCurrent = g_temp.numNext;
13520		g_temp.numNext = currentNum;
13521		
13522		g_objThis.trigger(t.events.ITEM_CHANGED);
13523		
13524		slides.objNextSlide.stop(true);		
13525		slides.objCurrentSlide.stop(true);
13526		
13527		if(noAnimation == true){
13528			
13529			slides.objCurrentSlide.fadeTo(0, 0);
13530			slides.objNextSlide.fadeTo(0, 1);	
13531			t.placeNabourItems();
13532			g_objThis.trigger(t.events.TRANSITION_END);
13533			
13534			if(noHidePlayer !== true)
13535				g_objVideoPlayer.hide();
13536		
13537		}else{
13538			slides.objNextSlide.fadeTo(0,0);	
13539			
13540			animateOpacity(slides.objCurrentSlide,0,function(){
13541				t.placeNabourItems();
13542				g_objThis.trigger(t.events.TRANSITION_END);
13543				if(noHidePlayer !== true)
13544					g_objVideoPlayer.hide();
13545			});
13546			
13547			if(g_objVideoPlayer.isVisible() == true){
13548				var videoElement = g_objVideoPlayer.getObject();
13549				animateOpacity(videoElement, 0);
13550			}
13551			
13552			//animate to next show next
13553			animateOpacity(slides.objNextSlide,1);			
13554		}
13555		
13556	}
13557	
13558	
13559	
13560	
13561	function __________CONTROLS_OBJECT_______(){};
13562	
13563	/**
13564	 * modify the slider for mobile
13565	 */
13566	function modifyForMobile(){
13567		
13568		if(g_options.slider_fullscreen_button_mobilehide == true && g_objButtonFullscreen)
13569			g_objButtonFullscreen.hide();
13570		
13571		if(g_options.slider_play_button_mobilehide == true && g_objButtonPlay)
13572			g_objButtonPlay.hide();
13573		
13574		if(g_options.slider_zoompanel_mobilehide == true && g_objZoomPanel)
13575			g_objZoomPanel.getElement().hide();
13576		
13577	}
13578	
13579	
13580	/**
13581	 * modify for no mobile
13582	 */
13583	function modifyForDesctop(){
13584		
13585		if(g_options.slider_fullscreen_button_mobilehide == true && g_objButtonFullscreen)
13586			g_objButtonFullscreen.show();
13587
13588		if(g_options.slider_play_button_mobilehide == true && g_objButtonPlay)
13589			g_objButtonPlay.show();
13590		
13591		if(g_options.slider_zoompanel_mobilehide == true && g_objZoomPanel)
13592			g_objZoomPanel.getElement().show();
13593		
13594	}
13595	
13596	
13597	/**
13598	 * check and modify for mobile or desctop
13599	 */
13600	function checkMobileModify(){
13601		
13602		var isMobile = g_gallery.isMobileMode();
13603		
13604		if(isMobile)
13605			modifyForMobile();
13606		else
13607			modifyForDesctop();
13608				
13609	}
13610	
13611	
13612	/**
13613	 * get a jquery set of the controls objects
13614	 */
13615	function getControlsObjects(){
13616		
13617		var objControl = g_objSlider.children(".ug-slider-control");
13618		
13619		return(objControl);
13620	}
13621	
13622	
13623	/**
13624	 * hide the controls
13625	 */
13626	function hideControls(noAnimation){
13627				
13628		if(g_functions.isTimePassed("sliderControlsToggle") == false)
13629			return(false);
13630		
13631		if(g_temp.isControlsVisible == false)
13632			return(false);
13633				
13634		if(!noAnimation)
13635			var noAnimation = false;
13636		
13637		var objControls = getControlsObjects();
13638		
13639		if(noAnimation === true)
13640			objControls.stop().fadeTo(0,0).hide();
13641		else{
13642			objControls.stop().fadeTo(g_options.slider_controls_appear_duration, 0, function(){objControls.hide()});
13643		}
13644		
13645		g_temp.isControlsVisible = false;
13646	}
13647	
13648	
13649	/**
13650	 * show controls only if they meaned to be shown
13651	 * @param noAnimation
13652	 */
13653	function checkAndShowControls(noAnimation){
13654		
13655		if(g_options.slider_controls_always_on == true)
13656			showControls(noAnimation);		
13657	}
13658	
13659	
13660	/**
13661	 * hide the controls
13662	 */
13663	function showControls(noAnimation){
13664				
13665		//validate for short time pass
13666		if(g_functions.isTimePassed("sliderControlsToggle") == false)
13667			return(false);
13668		
13669		if(g_temp.isControlsVisible == true)
13670			return(true);
13671		
13672		
13673		if(!noAnimation)
13674			var noAnimation = false;
13675		
13676		var objControls = getControlsObjects();
13677				
13678		if(noAnimation === true)
13679			objControls.stop().show();
13680		else{
13681		
13682			objControls.stop().show().fadeTo(0,0);
13683			objControls.fadeTo(g_options.slider_controls_appear_duration, 1);
13684			
13685		}
13686		
13687		g_temp.isControlsVisible = true;
13688		
13689	}
13690	
13691	
13692	
13693	/**
13694	 * toggle the controls (show, hide)
13695	 */
13696	function toggleControls(){
13697								
13698		if(g_temp.isControlsVisible == false)
13699			showControls();
13700		else
13701			hideControls();
13702	}
13703	
13704	
13705	/**
13706	 * set controls mode
13707	 * modes: image, video
13708	 */
13709	function setControlsMode(mode){
13710				
13711		if(mode == g_temp.currentControlsMode)
13712			return(false);
13713		
13714		switch(mode){
13715			case "image":
13716				if(g_objZoomPanel)
13717					g_objZoomPanel.getElement().show();			
13718			break;
13719			case "video":
13720				if(g_objZoomPanel)
13721					g_objZoomPanel.getElement().hide();	
13722			break;
13723			default:
13724				throw new Error("wrong controld mode: " + mode);
13725			break;
13726		}
13727		
13728		g_temp.currentControlsMode = mode;
13729			
13730	}
13731	
13732	
13733	
13734	function __________EVENTS___________(){};
13735
13736	/**
13737	 * on item change event
13738	 */
13739	function onItemChange(data, arg_objItem, role){
13740		
13741		//trace("slider on change");
13742		
13743		var objItem = g_gallery.getSelectedItem();
13744				
13745		t.setItem(objItem, false, role);
13746		
13747		var itemIndex = objItem.index;
13748		
13749		//set active bullet
13750		if(g_objBullets)
13751			g_objBullets.setActive(itemIndex);
13752		
13753		//handle text panel
13754		if(g_objTextPanel){			
13755			if(g_temp.isTextPanelSaparateHover == false)
13756				showTextPanel();
13757		}
13758				
13759		if(objItem.type == "image"){
13760			setControlsMode("image");
13761			//placeControlsElements();
13762		}
13763		else{
13764			setControlsMode("video");
13765		}
13766				
13767	}
13768	
13769	
13770	/**
13771	 * on bullet click - change the item to selected
13772	 */
13773	function onBulletClick(event, bulletIndex){
13774		g_gallery.selectItem(bulletIndex);		
13775	}
13776	
13777	
13778	/**
13779	 * on touch end
13780	 * toggle controls
13781	 */
13782	function onClick(event){
13783		
13784		//double tap action
13785		if(g_objTouchSlider && g_objTouchSlider.isTapEventOccured(event) == false)
13786			return(true);
13787		
13788		g_objThis.trigger(t.events.CLICK, event);
13789			
13790		
13791	}
13792
13793	
13794	/**
13795	 * on actual click event
13796	 */
13797	function onActualClick(){
13798
13799		//check link
13800		var currentSlide = t.getCurrentSlide();
13801		var isClickable = currentSlide.hasClass("ug-slide-clickable");
13802		var objItem = t.getCurrentItem();
13803		
13804		if(isClickable){
13805			
13806			//redirect to link
13807			if(g_options.slider_links_newpage == false){
13808				location.href = objItem.link;
13809			}else{
13810				window.open(objItem.link, '_blank');			
13811			}
13812			
13813			return(true);
13814		}
13815		
13816		//check toggle controls
13817		if(g_options.slider_controls_always_on == false && 
13818		   g_options.slider_controls_appear_ontap == true && t.isCurrentSlideType("image") == true){
13819			
13820			toggleControls();
13821			
13822			//show text panel if hidden
13823			if(g_objTextPanel && g_options.slider_textpanel_always_on == true && t.isCurrentSlideType("image") && t.isCurrentSlideImageFit())
13824				showTextPanel();
13825		}
13826		
13827		
13828	}
13829	
13830	
13831	/**
13832	 * on zoom start event
13833	 */
13834	function onZoomChange(event){
13835		
13836		if(g_objTextPanel && t.isCurrentSlideType("image") && t.isCurrentSlideImageFit() == false)
13837			hideTextPanel();
13838	}
13839	
13840	
13841	/**
13842	 * on mouse enter
13843	 */
13844	function onMouseEnter(){
13845		
13846		showControls();
13847	
13848	}
13849	
13850	
13851	/**
13852	 * on mouse leave
13853	 */
13854	function onMouseLeave(){
13855
13856		hideControls();
13857		
13858	}
13859	
13860	
13861	/**
13862	 * on slide video play button click
13863	 */
13864	function objVideoPlayClick(objButton){
13865		var objSlide = objButton.parent();
13866		t.startSlideAction(objSlide);
13867	}
13868
13869	/**
13870	 * on video player show event
13871	 */
13872	function onVideoPlayerShow(){
13873		
13874		if(g_gallery.isPlayMode()){
13875			g_gallery.pausePlaying();
13876		}
13877		
13878		g_objThis.trigger(t.events.ACTION_START);
13879	}
13880	
13881	
13882	/**
13883	 * on video player hide event
13884	 */
13885	function onVideoPlayerHide(){
13886		
13887		if(g_gallery.isPlayMode()){
13888			g_gallery.continuePlaying();
13889		}
13890		
13891		g_objThis.trigger(t.events.ACTION_END);		
13892	}
13893	
13894	
13895	/**
13896	 * on item image update, update the image inside the slider if relevant
13897	 */
13898	function onItemImageUpdate(event, index, urlImage){
13899				
13900		if(g_objSlide1.data("index") == index){
13901			objItem = g_gallery.getItem(index);
13902			setImageToSlide(g_objSlide1, objItem, true);	//force
13903		}
13904		
13905		if(g_objSlide2.data("index") == index){
13906			objItem = g_gallery.getItem(index);
13907			setImageToSlide(g_objSlide2, objItem, true);
13908		}
13909		
13910		if(g_objSlide3.data("index") == index){
13911			objItem = g_gallery.getItem(index);
13912			setImageToSlide(g_objSlide3, objItem, true);
13913		}
13914		
13915	}
13916	
13917	
13918	/**
13919	 * after image loaded. position video play button
13920	 */
13921	function onSlideImageLoaded(data, objSlide){
13922		
13923		objSlide = jQuery(objSlide);
13924		var objImage = t.getSlideImage(objSlide);
13925		var objButtonVideoPlay = getSlideVideoPlayButton(objSlide);
13926		var objSize = g_functions.getElementSize(objImage);
13927		
13928		g_functions.placeElement(objButtonVideoPlay, "center", "middle", objSize.left, objSize.top, objImage);
13929	}
13930	
13931	
13932	/**
13933	 * init event of current slide
13934	 */
13935	function initSlideEvents(objSlide){
13936		
13937		//set video player events
13938		var objVideoPlayButton = getSlideVideoPlayButton(objSlide);
13939		g_functions.addClassOnHover(objVideoPlayButton);
13940		
13941		g_functions.setButtonOnClick(objVideoPlayButton, objVideoPlayClick);
13942		
13943	}
13944	
13945	
13946	/**
13947	 * init events
13948	 */
13949	function initEvents(){
13950		
13951		//on item image update, update the image inside the slider if relevant
13952		g_objGallery.on(g_gallery.events.ITEM_IMAGE_UPDATED, onItemImageUpdate);
13953		
13954		
13955		//on item change, change the item in the slider.
13956		g_objGallery.on(g_gallery.events.ITEM_CHANGE, onItemChange);
13957		
13958		if(g_objBullets)
13959			jQuery(g_objBullets).on(g_objBullets.events.BULLET_CLICK,onBulletClick);
13960		
13961		//arrows events
13962		if(g_options.slider_enable_arrows == true){
13963			
13964			g_functions.addClassOnHover(g_objArrowRight, "ug-arrow-hover");
13965			g_functions.addClassOnHover(g_objArrowLeft, "ug-arrow-hover");
13966			
13967			g_gallery.setNextButton(g_objArrowRight);
13968			g_gallery.setPrevButton(g_objArrowLeft);
13969		}
13970		
13971		
13972		//show / hide controls
13973		if(g_options.slider_controls_always_on == false){
13974			
13975			//assign hover evens only if no touch device
13976			g_objSlider.hover(onMouseEnter, onMouseLeave);
13977			
13978		}
13979		
13980		//touch events appear on tap event
13981		g_objSlider.on("touchend click", onClick);
13982		
13983		//actual click event
13984		g_objThis.on(t.events.CLICK, onActualClick);
13985		
13986		//show / hide text panel, if it's saparate from controls
13987		if(g_objTextPanel && g_temp.isTextPanelSaparateHover == true){
13988			g_objSlider.hover(showTextPanel, hideTextPanel);
13989		}
13990		
13991		//init play / pause button
13992		if(g_objButtonPlay){
13993			g_functions.addClassOnHover(g_objButtonPlay, "ug-button-hover");
13994			g_gallery.setPlayButton(g_objButtonPlay);
13995		}
13996		
13997		//init fullscreen button
13998		if(g_objButtonFullscreen){
13999			g_functions.addClassOnHover(g_objButtonFullscreen, "ug-button-hover");
14000			g_gallery.setFullScreenToggleButton(g_objButtonFullscreen);
14001		}
14002		
14003		//on zoom start / end events
14004		if(g_objZoomSlider){
14005			g_objThis.on(t.events.ZOOM_CHANGE, onZoomChange);
14006		}
14007		
14008		if(g_objZoomPanel)
14009			g_objZoomPanel.initEvents();
14010				
14011		//init video player related events
14012		g_objVideoPlayer.initEvents();
14013		
14014		//video API events
14015		jQuery(g_objVideoPlayer).on(g_objVideoPlayer.events.SHOW, onVideoPlayerShow);		
14016		jQuery(g_objVideoPlayer).on(g_objVideoPlayer.events.HIDE, onVideoPlayerHide);
14017		
14018		//add slide events
14019		initSlideEvents(g_objSlide1);
14020		initSlideEvents(g_objSlide2);
14021		initSlideEvents(g_objSlide3);
14022		
14023		//on image loaded
14024		g_objThis.on(t.events.AFTER_PUT_IMAGE, onSlideImageLoaded);
14025		
14026		//image mouseenter / mouseleave event
14027		
14028		//set mouseover events on the images
14029		g_objSlider.delegate(".ug-item-wrapper img","mouseenter",function(event){
14030			g_objThis.trigger(t.events.IMAGE_MOUSEENTER);
14031		});
14032
14033		g_objSlider.delegate(".ug-item-wrapper img","mouseleave",function(event){
14034			var isMouseOver = t.isMouseInsideSlideImage(event);
14035			
14036			if(isMouseOver == false)
14037				g_objThis.trigger(t.events.IMAGE_MOUSELEAVE);
14038		});
14039		
14040	}
14041	
14042	
14043	/**
14044	 * destroy slider events
14045	 */
14046	this.destroy = function(){
14047		
14048		g_objThis.off(t.events.AFTER_PUT_IMAGE);
14049				
14050		g_objGallery.off(g_gallery.events.ITEM_IMAGE_UPDATED);
14051		g_objGallery.off(g_gallery.events.ITEM_CHANGE);
14052		
14053		if(g_objBullets)
14054			jQuery(g_objBullets).on(g_objBullets.events.BULLET_CLICK);
14055		
14056		g_objSlider.off("mouseenter");
14057		g_objSlider.off("mouseleave");
14058		
14059		g_objSlider.off("touchend");
14060		g_objSlider.off("click");
14061		g_objThis.off(t.events.CLICK);
14062		
14063		if(g_objZoomSlider)
14064			g_objThis.off(t.events.ZOOM_CHANGE);
14065		
14066		g_objThis.off(t.events.BEFORE_SWITCH_SLIDES);
14067		jQuery(g_objVideoPlayer).off(g_objVideoPlayer.events.SHOW);		
14068		jQuery(g_objVideoPlayer).off(g_objVideoPlayer.events.HIDE);
14069		
14070		g_objVideoPlayer.destroy();
14071		
14072		g_objSlider.undelegate(".ug-item-wrapper img","mouseenter");
14073		g_objSlider.undelegate(".ug-item-wrapper img","mouseleave");
14074	}
14075	
14076	
14077	function __________GETTERS___________(){};
14078	
14079	/**
14080	 * get loader class by loader type
14081	 */
14082	function getLoaderClass(){
14083		var loaderClass;
14084		switch(g_options.slider_loader_type){
14085			default:
14086			case 1: loaderClass = "ug-loader1";break;
14087			case 2: loaderClass = "ug-loader2";break;
14088			case 3: loaderClass = "ug-loader3";break;
14089			case 4: loaderClass = "ug-loader4";break;
14090			case 5: loaderClass = "ug-loader5";break;
14091			case 6: loaderClass = "ug-loader6";break;
14092			case 7: loaderClass = "ug-loader7";break;
14093			case 8: loaderClass = "ug-loader8";break;
14094			case 9: loaderClass = "ug-loader9";break;
14095		}
14096				
14097		if(g_options.slider_loader_color == "black")
14098			loaderClass += " ug-loader-black";
14099		
14100		return(loaderClass);
14101	}
14102	
14103	
14104	
14105	/**
14106	 * 
14107	 * get slide by number
14108	 */
14109	function getSlideByNum(num){
14110				
14111		switch(num){
14112			case 1:
14113				return(g_objSlide1);
14114			break;
14115			case 2:
14116				return(g_objSlide2);
14117			break;
14118			case 3:
14119				return(g_objSlide3);
14120			break;
14121			default:
14122				throw new Error("wrong num: " + num);
14123			break;
14124		}
14125	}
14126	
14127	
14128	/**
14129	 * 
14130	 * get slide direction of current item
14131	 */
14132	function getSlideDirection(objItem){
14133		
14134		var slides = t.getSlidesReference();
14135		
14136		//validate if the item is not selected already
14137		var currentIndex = slides.objCurrentSlide.data("index");
14138		var nextIndex = objItem.index;
14139		
14140		var direction = "left";
14141		if(currentIndex > nextIndex)
14142			direction = "right";
14143				
14144		return(direction);
14145	}
14146	
14147	
14148	/**
14149	 * get slide preloader
14150	 */
14151	function getSlidePreloader(objSlide){
14152		
14153		if(!objSlide)
14154			var objSlide = t.getCurrentSlide();
14155		
14156		var objPreloader = objSlide.children(".ug-slider-preloader");
14157		return(objPreloader);
14158	}
14159	
14160	/**
14161	 * get slide videoplay button
14162	 */
14163	function getSlideVideoPlayButton(objSlide){
14164		var objButton = objSlide.children(".ug-button-videoplay");
14165		return(objButton);
14166	}
14167	
14168	
14169	
14170	/**
14171	 * get slide item
14172	 */
14173	function getSlideItem(objSlide){
14174		if(!objSlide)
14175			var objSlide = t.getCurrentSlide();
14176			
14177		var index = objSlide.data("index");
14178		if(index == undefined)
14179			return(null);
14180		
14181		var objItem = g_gallery.getItem(index);
14182		return(objItem);
14183	}
14184	
14185	
14186	/**
14187	 * get slide number
14188	 */
14189	function getNumSlide(objSlide){
14190		var numSlide = objSlide.data("slidenum");
14191		return(numSlide);
14192	}
14193	
14194	
14195	
14196	this.________EXTERNAL_GENERAL___________ = function(){};
14197	
14198	
14199	/**
14200	 * init function for avia controls
14201	 * options: width / height
14202	 */
14203	this.init = function(objGallery, objOptions, optionsPrefix){
14204				
14205		initSlider(objGallery, objOptions, optionsPrefix);
14206	}
14207
14208	/**
14209	 * get slide image
14210	 */
14211	this.getSlideImage = function(objSlide){
14212		
14213		if(!objSlide)
14214			var objSlide = t.getCurrentSlide();
14215		
14216		var objImage = objSlide.find(".ug-item-wrapper img");
14217		return(objImage);
14218	}
14219	
14220	
14221	/**
14222	 * set slider html
14223	 */
14224	this.setHtml = function(objParent){
14225		
14226		setHtmlSlider(objParent);
14227	}
14228	
14229	
14230	/**
14231	 * run the slider
14232	 */
14233	this.run = function(){
14234		
14235		runSlider();
14236	}
14237	
14238	
14239	/**
14240	 * check if the inner object in place, for panning znd zooming posibility check
14241	 */
14242	this.isInnerInPlace = function(){
14243		
14244		var slides = t.getSlidesReference();
14245		
14246		var posCurrent = g_functions.getElementSize(slides.objCurrentSlide);
14247		var inPlaceX = -posCurrent.left;
14248		var objInnerSize = g_functions.getElementSize(g_objInner);
14249		
14250		if(inPlaceX == objInnerSize.left)
14251			return(true);
14252		else
14253			return(false);
14254	}
14255	
14256	/**
14257	 * is animating
14258	 */
14259	this.isAnimating = function(){
14260		
14261		var isAnimated = g_objInner.is(":animated");
14262		
14263		return(isAnimated);
14264	}
14265	
14266	/**
14267	 * check if the slide is current
14268	 */
14269	this.isSlideCurrent = function(objSlide){
14270		var numSlide = objSlide.data("slidenum");
14271		if(g_temp.numCurrent == numSlide)
14272			return(true);
14273		
14274		return(false);
14275	}
14276	
14277	
14278	/**
14279	 * 
14280	 * tells if the slide has item
14281	 */
14282	this.isSlideHasItem = function(objSlide){
14283		var index = objSlide.data("index");
14284		if(index === undefined || index === null)
14285			return(false);
14286		
14287		return(true);
14288	}
14289	
14290	
14291	/**
14292	 * get image padding object for scaling the image
14293	 */
14294	this.getObjImagePadding = function(){
14295		
14296		var objPadding = {
14297				padding_top: g_options.slider_image_padding_top,
14298				padding_bottom: g_options.slider_image_padding_bottom,
14299				padding_left: g_options.slider_image_padding_left,
14300				padding_right: g_options.slider_image_padding_right
14301		};
14302		
14303		return(objPadding);
14304	}
14305			
14306	
14307	/**
14308	 * get items reference by their order
14309	 */
14310	this.getSlidesReference = function(){
14311		
14312		var obj = {
14313				objPrevSlide: getSlideByNum(g_temp.numPrev),
14314				objNextSlide: getSlideByNum(g_temp.numNext),
14315				objCurrentSlide: getSlideByNum(g_temp.numCurrent)
14316		};
14317		
14318		return(obj);
14319	}
14320	
14321	
14322	/**
14323	 * get current slide
14324	 */
14325	this.getCurrentSlide = function(){
14326		
14327		var slides = t.getSlidesReference();
14328		
14329		return(slides.objCurrentSlide);
14330	}
14331	
14332	
14333	/**
14334	 * get index of current item
14335	 */
14336	this.getCurrentItemIndex = function(){
14337		
14338		var slides = t.getSlidesReference();
14339		
14340		var currentIndex = slides.objCurrentSlide.data("index");
14341		if(currentIndex === null || currentIndex === undefined)
14342			currentIndex = -1;
14343		
14344		return(currentIndex);
14345	}
14346	
14347	
14348	/**
14349	 * get current slide item
14350	 */
14351	this.getCurrentItem = function(){
14352		var currentIndex = t.getCurrentItemIndex();
14353		if(currentIndex == -1)
14354			return(null);
14355		
14356		var objItem = g_gallery.getItem(currentIndex);
14357		
14358		return(objItem);
14359	}
14360		
14361	
14362	/**
14363	 * get type of some slide
14364	 */
14365	this.getSlideType = function(objSlide){
14366		
14367		if(objSlide == undefined)
14368			objSlide = t.getCurrentSlide();
14369			
14370		var type = objSlide.data("type");
14371		return(type);		
14372	}
14373
14374	
14375	/**
14376	 * is mouse inside slide image
14377	 * get mouse position from event
14378	 */
14379	this.isMouseInsideSlideImage = function(event){
14380		
14381		var objImage = t.getSlideImage();
14382		
14383		var point = g_functions.getMousePosition(event);
14384		if(point.pageX === undefined)
14385			point = g_objTouchSlider.getLastMousePos();
14386		
14387		var pointImg = g_functions.getMouseElementPoint(point, objImage);
14388		var objSize = g_functions.getElementSize(objImage);
14389		isMouseInside = g_functions.isPointInsideElement(pointImg, objSize);
14390		
14391		return(isMouseInside);
14392	}
14393	
14394	
14395	/**
14396	 * check if current slide type is certain type
14397	 */
14398	this.isCurrentSlideType = function(type){
14399		var currentSlideType = t.getSlideType();
14400		if(currentSlideType == type)
14401			return(true);
14402		
14403		return(false);
14404	}
14405	
14406	
14407	/**
14408	 * check if current slide is loading image
14409	 */
14410	this.isCurrentSlideLoadingImage = function(){
14411		var currentSlide = t.getCurrentSlide();
14412		var isLoading = currentSlide.data("isLoading");
14413		if(isLoading === true)
14414			return(true);
14415		
14416		return(false);
14417	}
14418	
14419	
14420	/**
14421	 * change the slider to some item content
14422	 */
14423	this.setItem = function(objItem, forseTransition, role){
14424		
14425		var slides = t.getSlidesReference();
14426		
14427		//validate if the item is not selected already
14428		var currentIndex = slides.objCurrentSlide.data("index");
14429		var nextIndex = objItem.index;
14430		
14431		if(nextIndex == currentIndex){
14432			return(true);
14433		}
14434		
14435		var isFirstSlide = (currentIndex == undefined);
14436		
14437		if(isFirstSlide){			
14438			setItemToSlide(slides.objCurrentSlide, objItem);
14439			t.placeNabourItems();
14440			
14441		}else{
14442			
14443			var direction = "left";		//move foreward
14444			
14445			var numItems = g_gallery.getNumItems();
14446			
14447			if(role == "next")
14448				direction = "left";
14449			else if(role == "prev" || currentIndex > nextIndex)
14450				direction = "right";
14451			else if(currentIndex > nextIndex)
14452					direction = "right";
14453						
14454			doTransition(direction, objItem, forseTransition);
14455		}
14456					
14457	}
14458	
14459	
14460	/**
14461	 * when the transition complete, put the next / prev items at their place
14462	 */
14463	this.placeNabourItems = function(){
14464				
14465		var slides = t.getSlidesReference();
14466		var currentIndex = slides.objCurrentSlide.data("index");
14467				
14468		var itemPrev = g_gallery.getPrevItem(currentIndex);
14469		var itemNext = g_gallery.getNextItem(currentIndex);
14470		
14471		//trace(itemPrev);
14472		//trace(itemNext);
14473		
14474		//trace("place " + currentIndex, "next: "+);
14475		
14476		setItemToSlide(slides.objNextSlide, itemNext);
14477		setItemToSlide(slides.objPrevSlide, itemPrev);
14478		
14479		positionSlides();
14480	}
14481	
14482	
14483	
14484	this.________EXTERNAL_API___________ = function(){};
14485	
14486	
14487	/**
14488	 * stop some slide action if active
14489	 */
14490	this.stopSlideAction = function(objSlide, isPause){
14491		
14492		if(!objSlide)
14493			objSlide = t.getCurrentSlide();
14494		
14495		if(isPause === true)
14496			g_objVideoPlayer.pause();
14497		else
14498			g_objVideoPlayer.hide();
14499		
14500	//	trace("stop action");
14501		
14502	}
14503	
14504	
14505	
14506	/**
14507	 * start some slide action if exists
14508	 */
14509	this.startSlideAction = function(objSlide){
14510		
14511	//	trace("start action");
14512		
14513		if(!objSlide)
14514			objSlide = t.getCurrentSlide();
14515		
14516		var objItem = getSlideItem(objSlide);
14517		
14518		if(objItem.type == "image")
14519			return(true)
14520		
14521		if(g_options.slider_video_constantsize == true)
14522			setVideoPlayerConstantSize();
14523		
14524		setVideoPlayerPosition();
14525		
14526		g_objVideoPlayer.show();
14527		
14528		switch(objItem.type){
14529			case "youtube":
14530				g_objVideoPlayer.playYoutube(objItem.videoid);
14531			break;
14532			case "vimeo":
14533				g_objVideoPlayer.playVimeo(objItem.videoid);
14534			break;
14535			case "html5video":
14536				g_objVideoPlayer.playHtml5Video(objItem.videoogv, objItem.videowebm, objItem.videomp4, objItem.urlImage);
14537			break;
14538			case "soundcloud":
14539				g_objVideoPlayer.playSoundCloud(objItem.trackid);
14540			break;			
14541			case "wistia":
14542				g_objVideoPlayer.playWistia(objItem.videoid);
14543			break;			
14544		}
14545		
14546	}
14547	
14548	
14549	/**
14550	 * get the scale mode according the state (normal, fullscreen).
14551	 */
14552	this.getScaleMode = function(objSlide){
14553		
14554		if(!objSlide)
14555			var objSlide = t.getCurrentSlide();
14556		
14557		var slideType = t.getSlideType(objSlide);
14558				
14559		//return media scale mode
14560		if(slideType != "image")
14561			return(g_options.slider_scale_mode_media);
14562		
14563		if(g_options.slider_scale_mode == g_options.slider_scale_mode_fullscreen)
14564			return(g_options.slider_scale_mode);
14565		
14566		if(g_gallery.isFullScreen() == true)
14567			return(g_options.slider_scale_mode_fullscreen);
14568		else
14569			return(g_options.slider_scale_mode);
14570		
14571	}
14572	
14573	
14574	/**
14575	 * get slider objects
14576	 */
14577	this.getObjects = function(){
14578		
14579		var obj = {
14580				g_objSlider: g_objSlider,
14581				g_objInner: g_objInner,
14582				g_options: g_options,
14583				g_objZoomSlider: g_objZoomSlider
14584		};
14585				
14586		return(obj);
14587	}
14588	
14589	
14590	/**
14591	 * get zoom object
14592	 */
14593	this.getObjZoom = function(){
14594		
14595		return(g_objZoomSlider);
14596	}
14597	
14598	
14599	
14600	/**
14601	 * get slider options
14602	 */
14603	this.getOptions = function(){
14604		
14605		return(g_options);
14606	}
14607	
14608	
14609	/**
14610	 * get slider element
14611	 */
14612	this.getElement = function(){
14613		
14614		return(g_objSlider);
14615	}
14616	
14617	/**
14618	 * get video object
14619	 */
14620	this.getVideoObject = function(){
14621		return(g_objVideoPlayer);
14622	}
14623	
14624	
14625	/**
14626	 * return true if current slider image fit the slider
14627	 * @returns
14628	 */
14629	this.isCurrentSlideImageFit = function(){
14630		var objSlide = t.getCurrentSlide();
14631
14632		var slideType = t.getSlideType(objSlide);
14633		
14634		validateSlideType("image", objSlide);
14635		
14636		var objImage = t.getSlideImage(objSlide);
14637		
14638		//if image don't yet added to dom, return false
14639		if(objImage.length == 0)
14640			return(false);
14641		
14642		var isFit = g_functions.isImageFitParent(objImage);
14643		
14644		return(isFit);
14645	}
14646	
14647	
14648	/**
14649	 * check if current image in place
14650	 */
14651	this.isCurrentImageInPlace = function(){
14652		
14653		var objImage = t.getSlideImage();
14654		if(objImage.length == 0)
14655			return(false);
14656
14657		var scaleMode = t.getScaleMode();
14658		var objPadding = t.getObjImagePadding();
14659		var objItem = getSlideItem();
14660		
14661		var objParent = objImage.parent();
14662		
14663		var objFitSize = g_functions.getImageInsideParentData(objParent, objItem.imageWidth, objItem.imageHeight, scaleMode, objPadding);
14664		var objSize = g_functions.getElementSize(objImage);
14665
14666		var output = false;
14667		
14668		if(objFitSize.imageWidth == objSize.width)
14669			output = true;
14670				
14671		return(output);
14672	}
14673	
14674	
14675	/**
14676	 * if slide is bussy in some action
14677	 */
14678	this.isSlideActionActive = function(){
14679		
14680		return g_objVideoPlayer.isVisible();
14681	}
14682	
14683	/**
14684	 * return if swipe action active
14685	 */
14686	this.isSwiping = function(){
14687		if(!g_objTouchSlider)
14688			return(false);
14689		
14690		var isActive = g_objTouchSlider.isTouchActive();
14691		
14692		return(isActive);
14693	}
14694	
14695	
14696	/**
14697	 * if slider preloading image (if preloader visible)
14698	 */
14699	this.isPreloading = function(){
14700		
14701		var objPreloader = getSlidePreloader();
14702		if(objPreloader.is(":visible"))
14703			return(true);
14704		
14705		return(false);
14706	}
14707	
14708	/**
14709	 * set the options
14710	 */
14711	this.setOptions = function(objOptions){
14712
14713		//change options by prefix
14714		if(g_optionsPrefix)
14715			objOptions = g_functions.convertCustomPrefixOptions(objOptions, g_optionsPrefix, "slider");
14716		
14717		g_options = jQuery.extend(g_options, objOptions);
14718		
14719	}
14720	
14721	
14722	/**
14723	 * set the slider size
14724	 * works well on resize too.
14725	 */
14726	this.setSize = function(width, height){
14727		
14728		 if(width < 0 || height < 0)
14729			 return(true);
14730		
14731		 var objCssSlider = {};
14732		 objCssSlider["width"] = width + "px";
14733		 objCssSlider["height"] = height + "px";
14734		 g_objSlider.css(objCssSlider);
14735		 		 
14736		 //set inner:
14737		 var objCssInner = {};
14738		 objCssInner["height"] = height + "px";
14739		 objCssInner["top"] = "0px";
14740		 objCssInner["left"] = "0px";
14741		 g_objInner.css(objCssInner);
14742		 
14743		//set slide wrapper
14744		 var objCssSlide = {};
14745		 objCssSlide["height"] = height + "px";
14746		 objCssSlide["width"] = width + "px";
14747		 
14748		 g_objSlide1.css(objCssSlide);
14749		 g_objSlide2.css(objCssSlide);
14750		 g_objSlide3.css(objCssSlide);
14751		 
14752		 var itemWidth = width - g_options.slider_item_padding_left - g_options.slider_item_padding_right;
14753		 var itemHeight = height - g_options.slider_item_padding_top - g_options.slider_item_padding_bottom;
14754		 	
14755		 //set item wrapper
14756		 var objCssItemWrapper = {};
14757		 objCssItemWrapper["width"] = itemWidth + "px";
14758		 objCssItemWrapper["height"] = itemHeight + "px";
14759		 objCssItemWrapper["top"] = g_options.slider_item_padding_top + "px";
14760		 objCssItemWrapper["left"] = g_options.slider_item_padding_left + "px";
14761		 
14762		 g_objSlider.find(".ug-item-wrapper").css(objCssItemWrapper);		 
14763		 
14764		 
14765		 //set text panel size
14766		 if(g_objTextPanel){
14767			 g_objTextPanel.setSizeByParent();
14768		 }
14769		 
14770		 positionElements();
14771		 
14772		 //set image to slides
14773		 resizeSlideItem(g_objSlide1);
14774		 resizeSlideItem(g_objSlide2);
14775		 resizeSlideItem(g_objSlide3);
14776		 
14777		 positionSlides();
14778		 		 
14779		 //set video player size
14780		 var currentSlideType = t.getSlideType();
14781		
14782		 if(currentSlideType != "image" && g_options.slider_video_constantsize == true){
14783			 
14784			 setVideoPlayerConstantSize();
14785		 }else{	
14786			 var videoWidth = width - g_options.slider_video_padding_left - g_options.slider_video_padding_right;
14787			 var videoHeight = height - g_options.slider_video_padding_top - g_options.slider_video_padding_bottom;
14788			 
14789			 //set video player size
14790			 g_objVideoPlayer.setSize(videoWidth, videoHeight);
14791		 }
14792		 
14793		 setVideoPlayerPosition();
14794		 
14795	}
14796	
14797	
14798	/**
14799	 * refresh slide items after options change
14800	 */
14801	this.refreshSlideItems = function(){
14802		 
14803		if(t.isAnimating() == true)
14804			return(true);
14805		
14806		 resizeSlideItem(g_objSlide1);
14807		 resizeSlideItem(g_objSlide2);
14808		 resizeSlideItem(g_objSlide3);
14809		 positionSlides();
14810		 
14811	}
14812	
14813	
14814	/**
14815	 * is mouse over the slider
14816	 */
14817	this.isMouseOver = function(){
14818		
14819		return g_objSlider.ismouseover();
14820	}
14821	
14822	/**
14823	 * set slider position
14824	 */
14825	this.setPosition = function(left, top){
14826		
14827		g_functions.placeElement(g_objSlider, left, top);
14828			
14829	}
14830	
14831	
14832	/**
14833	 * zoom in
14834	 */
14835	this.zoomIn = function(){
14836		if(!g_objZoomSlider)
14837			return(true);
14838		
14839		g_objZoomSlider.zoomIn();
14840	}
14841	
14842	/**
14843	 * zoom out
14844	 */
14845	this.zoomOut = function(){
14846		
14847		if(!g_objZoomSlider)
14848			return(true);
14849		
14850		g_objZoomSlider.zoomOut();
14851			
14852	}
14853	
14854	/**
14855	 * zoom back to original
14856	 */
14857	this.zoomBack = function(){
14858		
14859		if(!g_objZoomSlider)
14860			return(true);
14861		
14862		g_objZoomSlider.zoomBack();	
14863	}
14864	
14865	
14866}
14867
14868/** -------------- TextPanel class ---------------------*/
14869
14870function UGTextPanel(){
14871	
14872	var t = this;
14873	var g_objPanel, g_objParent, g_objTitle, g_objDesc;
14874	var g_objBG, g_objTextWrapper, g_gallery;
14875	var g_functions = new UGFunctions(), g_optionsPrefix = "";
14876	
14877	var g_options = {
14878			textpanel_align:"bottom",					//(top , bottom), textpanel align according the parent
14879			textpanel_margin:0,							//margin from the textpanel position according the textpanel_align
14880			textpanel_text_valign:"middle",				//middle, top, bottom - text vertical align
14881			textpanel_padding_top:10,					//textpanel padding top 
14882			textpanel_padding_bottom:10,				//textpanel padding bottom
14883			textpanel_height: null,						//textpanel height. if null it will be set dynamically
14884			textpanel_padding_title_description: 5,		//the space between the title and the description
14885			textpanel_padding_right: 11,				//cut some space for text from right
14886			textpanel_padding_left: 11,					//cut some space for text from left
14887			textpanel_fade_duration: 200,				//the fade duration of textpanel appear
14888			textpanel_enable_title: true,				//enable the title text
14889			textpanel_enable_description: true,			//enable the description text
14890			textpanel_enable_bg: true,					//enable the textpanel background
14891			textpanel_bg_color:"#000000",				//textpanel background color
14892			textpanel_bg_opacity: 0.4,					//textpanel background opacity
14893			
14894			textpanel_title_color:null,					//textpanel title color. if null - take from css
14895			textpanel_title_font_family:null,			//textpanel title font family. if null - take from css
14896			textpanel_title_text_align:null,			//textpanel title text align. if null - take from css
14897			textpanel_title_font_size:null,				//textpanel title font size. if null - take from css
14898			textpanel_title_bold:null,					//textpanel title bold. if null - take from css
14899			textpanel_css_title:{},						//textpanel additional css of the title
14900
14901			textpanel_desc_color:null,					//textpanel description font family. if null - take from css
14902			textpanel_desc_font_family:null,			//textpanel description font family. if null - take from css
14903			textpanel_desc_text_align:null,				//textpanel description text align. if null - take from css
14904			textpanel_desc_font_size:null,				//textpanel description font size. if null - take from css
14905			textpanel_desc_bold:null,					//textpanel description bold. if null - take from css
14906			textpanel_css_description:{},				//textpanel additional css of the description
14907			
14908			textpanel_desc_style_as_title: false,		//set that the description style will be as title
14909			
14910			textpanel_bg_css:{}							//textpanel background css
14911	};
14912	
14913	var g_temp = {
14914			isFirstTime: true,
14915			setInternalHeight: true		//flag if set internal height or not
14916	};
14917	
14918	
14919	/**
14920	 * position elements from top
14921	 */
14922	function positionElementsTop(animateHeight, startY){
14923		
14924		if(!startY)
14925			var startY = g_options.textpanel_padding_top;
14926		
14927		//place title
14928		var maxy = startY;
14929		
14930		//place title
14931		if(g_objTitle){
14932			var titleY = maxy;
14933			g_functions.placeElement(g_objTitle, 0, titleY);
14934			
14935			var objTitleSize = g_functions.getElementSize(g_objTitle);		
14936						
14937			var maxy = objTitleSize.bottom;			
14938		}
14939		
14940		//place description
14941		var textDesc = "";
14942		if(g_objDesc)
14943			textDesc = jQuery.trim(g_objDesc.text());
14944		
14945		if(textDesc != ""){
14946			
14947			var descY = maxy;
14948						
14949			if(g_objTitle)
14950				descY += g_options.textpanel_padding_title_description;
14951			
14952			g_functions.placeElement(g_objDesc, 0, descY);
14953			var objDescSize = g_functions.getElementSize(g_objDesc);		
14954			maxy = objDescSize.bottom;
14955		}
14956		
14957		//change panel height
14958		if(!g_options.textpanel_height && g_temp.setInternalHeight == true){
14959			
14960			var panelHeight = maxy + g_options.textpanel_padding_bottom;		
14961			
14962			setHeight(panelHeight, animateHeight);
14963		}
14964		
14965	}
14966	
14967	/**
14968	 * get total text and description height
14969	 */
14970	function getTotalTextHeight(){
14971		var totalHeight = 0;
14972		
14973		if(g_objTitle)
14974			totalHeight += g_objTitle.outerHeight();
14975		
14976		if(g_objDesc){
14977			var textDesc = "";
14978			if(g_objDesc)
14979				textDesc = jQuery.trim(g_objDesc.text());
14980			
14981			if(textDesc != ""){
14982				if(g_objTitle)
14983					totalHeight += g_options.textpanel_padding_title_description;
14984				
14985				totalHeight += g_objDesc.outerHeight();
14986			}
14987		
14988		}
14989		
14990		
14991		return(totalHeight);
14992	}
14993	
14994	
14995	/**
14996	 * position elements to center
14997	 */
14998	function positionElementsMiddle(){
14999		
15000		var totalTextHeight = getTotalTextHeight();
15001		var startY = (g_objTextWrapper.height() - totalTextHeight) / 2;
15002		
15003		positionElementsTop(false, startY);
15004	}
15005	
15006	
15007	/**
15008	 * position elements to bottom
15009	 */
15010	function positionElementBottom(){
15011		
15012		var totalTextHeight = getTotalTextHeight();
15013		var startY = g_objTextWrapper.height() - totalTextHeight - g_options.textpanel_padding_bottom;
15014		
15015		positionElementsTop(false, startY);
15016	}
15017	
15018	
15019	/**
15020	 * position elements inside the panel
15021	 */
15022	this.positionElements = function(animateHeight){
15023
15024		//if(g_objPanel.is(":visible") == false)
15025			//trace("the text panel is hidden. can't position elements")
15026		
15027		//if height not set, position only top
15028		if(!g_options.textpanel_height || g_options.textpanel_text_valign == "top"){
15029			positionElementsTop(animateHeight);
15030			return(false);
15031		}
15032		
15033		switch(g_options.textpanel_text_valign){
15034			default:
15035			case "top":
15036				positionElementsTop(false);		//no animation in this case
15037			break;
15038			case "bottom":
15039				positionElementBottom();
15040			break;
15041			case "center":
15042			case "middle":
15043				positionElementsMiddle();
15044			break;
15045		}
15046		
15047	}
15048	
15049	
15050	/**
15051	 * set new panel height
15052	 */
15053	function setHeight(height, animateHeight){
15054		
15055		if(!animateHeight)
15056			var animateHeight = false;
15057		
15058		if(animateHeight == true){
15059			
15060			if(g_objBG){
15061				
15062				//avoid background jumps
15063				var currentHeight = g_objBG.height();
15064				if(height > currentHeight)
15065					g_objBG.height(height);				
15066			}
15067			
15068			var objCss = {height: height+"px"};
15069			g_objPanel.add(g_objTextWrapper).animate(objCss, g_options.textpanel_fade_duration);
15070			
15071		}else{
15072			
15073			if(g_objBG)
15074				g_objBG.height(height);		
15075			
15076			g_objPanel.add(g_objTextWrapper).height(height);
15077		}
15078		
15079	}
15080	
15081	
15082	
15083	
15084	/**
15085	 * init the panel
15086	 */
15087	this.init = function(objGallery, customOptions, optionsPrefix){
15088				
15089		g_gallery = objGallery;
15090		
15091		//change options by prefix
15092		if(optionsPrefix){
15093			g_optionsPrefix = optionsPrefix;
15094			customOptions = g_functions.convertCustomPrefixOptions(customOptions,g_optionsPrefix,"textpanel");			
15095			
15096		}
15097		
15098		if(customOptions)
15099			g_options = jQuery.extend(g_options, customOptions);
15100		
15101		//validation:
15102		if(g_options.textpanel_enable_title == false && g_options.textpanel_enable_description == false)
15103			throw new Error("Textpanel Error: The title or description must be enabled");
15104		
15105		if(g_options.textpanel_height && g_options.textpanel_height < 0)
15106			g_options.textpanel_height = null;
15107		
15108		//copy desc style from title
15109		if(g_options.textpanel_desc_style_as_title == true){
15110			if(!g_options.textpanel_desc_color)
15111				g_options.textpanel_desc_color = g_options.textpanel_title_color;
15112			
15113			if(!g_options.textpanel_desc_bold)
15114				g_options.textpanel_desc_bold = g_options.textpanel_title_bold;
15115			
15116			if(!g_options.textpanel_desc_font_family)
15117				g_options.textpanel_desc_font_family = g_options.textpanel_title_font_family;
15118			
15119			if(!g_options.textpanel_desc_font_size)
15120				g_options.textpanel_desc_font_size = g_options.textpanel_title_font_size;
15121			
15122			if(!g_options.textpanel_desc_text_align)
15123				g_options.textpanel_desc_text_align = g_options.textpanel_title_text_align;
15124		}
15125		
15126	}
15127	
15128	
15129	/**
15130	 * append the bullets html to some parent
15131	 */
15132	this.appendHTML = function(objParent, addClass){
15133		g_objParent = objParent;
15134		
15135		if(addClass){
15136			addClass = " "+addClass;
15137		}else
15138			addClass = "";
15139		
15140		var html = "<div class='ug-textpanel"+addClass+"'>";
15141		
15142		if(g_options.textpanel_enable_bg == true)
15143			html += "<div class='ug-textpanel-bg"+addClass+"'></div>";
15144		
15145		html += "<div class='ug-textpanel-textwrapper"+addClass+"'>";
15146		
15147		if(g_options.textpanel_enable_title == true)
15148			html += "<div class='ug-textpanel-title"+addClass+"'></div>";
15149		
15150		if(g_options.textpanel_enable_description == true)
15151			html += "<div class='ug-textpanel-description"+addClass+"'></div>";
15152		
15153		html += "</div></div>";
15154		
15155		objParent.append(html);
15156		
15157		g_objPanel = objParent.children(".ug-textpanel");
15158		g_objTextWrapper = g_objPanel.children(".ug-textpanel-textwrapper");
15159		
15160		setCss();
15161		
15162	}
15163	
15164	
15165	/**
15166	 * set panel css according the options
15167	 */
15168	function setCss(){
15169				
15170		//set background css		
15171		if(g_options.textpanel_enable_bg == true){
15172			g_objBG = g_objPanel.children(".ug-textpanel-bg");
15173			g_objBG.fadeTo(0,g_options.textpanel_bg_opacity);
15174			
15175			var objCssBG = {"background-color":g_options.textpanel_bg_color};
15176			objCssBG = jQuery.extend(objCssBG, g_options.textpanel_bg_css);
15177			
15178			g_objBG.css(objCssBG);
15179		}
15180		
15181		
15182		//set title css from options
15183		if(g_options.textpanel_enable_title == true){
15184			g_objTitle = g_objTextWrapper.children(".ug-textpanel-title");
15185			var objCssTitle = {};
15186			
15187			if(g_options.textpanel_title_color !== null)
15188				objCssTitle["color"] = g_options.textpanel_title_color;
15189			
15190			if(g_options.textpanel_title_font_family !== null)
15191				objCssTitle["font-family"] = g_options.textpanel_title_font_family;
15192			
15193			if(g_options.textpanel_title_text_align !== null)
15194				objCssTitle["text-align"] = g_options.textpanel_title_text_align;
15195			
15196			if(g_options.textpanel_title_font_size !== null)
15197				objCssTitle["font-size"] = g_options.textpanel_title_font_size+"px";
15198			
15199			if(g_options.textpanel_title_bold !== null){
15200				
15201				if(g_options.textpanel_title_bold === true)
15202					objCssTitle["font-weight"] = "bold";
15203				else
15204					objCssTitle["font-weight"] = "normal";
15205			
15206			}
15207			
15208			//set additional css
15209			if(g_options.textpanel_css_title)
15210				objCssTitle = jQuery.extend(objCssTitle, g_options.textpanel_css_title);
15211			
15212			g_objTitle.css(objCssTitle);
15213		}
15214		
15215		//set description css
15216		if(g_options.textpanel_enable_description == true){
15217			g_objDesc = g_objTextWrapper.children(".ug-textpanel-description");
15218			
15219			var objCssDesc = {};
15220			
15221			if(g_options.textpanel_desc_color !== null)
15222				objCssDesc["color"] = g_options.textpanel_desc_color;
15223			
15224			if(g_options.textpanel_desc_font_family !== null)
15225				objCssDesc["font-family"] = g_options.textpanel_desc_font_family;
15226			
15227			if(g_options.textpanel_desc_text_align !== null)
15228				objCssDesc["text-align"] = g_options.textpanel_desc_text_align;
15229			
15230			if(g_options.textpanel_desc_font_size !== null)
15231				objCssDesc["font-size"] = g_options.textpanel_desc_font_size+"px";
15232			
15233			if(g_options.textpanel_desc_bold !== null){
15234				
15235				if(g_options.textpanel_desc_bold === true)
15236					objCssDesc["font-weight"] = "bold";
15237				else
15238					objCssDesc["font-weight"] = "normal";
15239			
15240			}
15241			
15242			//set additional css
15243			if(g_options.textpanel_css_title)
15244				objCssDesc = jQuery.extend(objCssDesc, g_options.textpanel_css_description);
15245				
15246			g_objDesc.css(objCssDesc);
15247		}
15248		
15249	}
15250	
15251	/**
15252	 * on item change, set the text
15253	 */
15254	function onItemChange(){
15255		var objItem = g_gallery.getSelectedItem();
15256		t.setText(objItem.title, objItem.description);
15257	}
15258	
15259	
15260	/**
15261	 * init events
15262	 */
15263	function initEvents(){
15264		
15265		//on item change, set the text in the slider.
15266		jQuery(g_gallery).on(g_gallery.events.ITEM_CHANGE, onItemChange);
15267	}
15268	
15269	
15270	/**
15271	 * destroy the events
15272	 */
15273	this.destroy = function(){
15274		jQuery(g_gallery).off(g_gallery.events.ITEM_CHANGE);
15275	}
15276	
15277	/**
15278	 * run the text panel
15279	 */
15280	this.run = function(){
15281		
15282		t.setSizeByParent();
15283		
15284		initEvents();
15285	}
15286	
15287	/**
15288	 * set panel size
15289	 */
15290	this.setPanelSize = function(panelWidth, panelHeight){
15291		
15292		g_temp.setInternalHeight = true;
15293		
15294		if(!panelHeight)
15295			var panelHeight = 80;		//some default number
15296		else
15297			g_temp.setInternalHeight = false;
15298		
15299		if(g_options.textpanel_height)	
15300			panelHeight = g_options.textpanel_height;
15301		
15302		g_objPanel.width(panelWidth);
15303		g_objPanel.height(panelHeight);
15304		
15305		//set background size
15306		if(g_objBG){
15307			g_objBG.width(panelWidth);
15308			g_objBG.height(panelHeight);
15309		}
15310		
15311		//set textwrapper size and position
15312		var textWrapperWidth = panelWidth - g_options.textpanel_padding_left - g_options.textpanel_padding_right;
15313		var textWrapperLeft = g_options.textpanel_padding_left;
15314		
15315		g_functions.setElementSizeAndPosition(g_objTextWrapper, textWrapperLeft, 0, textWrapperWidth, panelHeight);
15316		
15317		//set text width
15318		if(g_objTitle)
15319			g_objTitle.width(textWrapperWidth);
15320		
15321		//set description height
15322		if(g_objDesc)
15323			g_objDesc.width(textWrapperWidth);
15324		
15325		if(g_temp.isFirstTime == false)
15326			t.positionElements(false);
15327	}
15328	
15329	
15330	/**
15331	 * set size by parent. the height is set to default meanwhile
15332	 */
15333	this.setSizeByParent = function(){
15334				
15335		var objSize = g_functions.getElementSize(g_objParent);
15336		t.setPanelSize(objSize.width);
15337	}
15338	
15339	/**
15340	 * set plain sext without other manipulations
15341	 */
15342	this.setTextPlain = function(title, description){
15343
15344		if(g_objTitle)
15345			g_objTitle.html(title);
15346		
15347		if(g_objDesc)
15348			g_objDesc.html(description);
15349		
15350	}
15351	
15352	
15353	/**
15354	 * set html text
15355	 */
15356	this.setText = function(title, description){
15357		
15358		if(g_temp.isFirstTime == true){
15359			
15360			t.setTextPlain(title, description);
15361			
15362			g_temp.isFirstTime = false;
15363			
15364			t.positionElements(false);
15365		
15366		}else{		//width animation
15367			
15368			g_objTextWrapper.stop().fadeTo(g_options.textpanel_fade_duration,0,function(){
15369				
15370				t.setTextPlain(title, description);
15371				
15372				t.positionElements(true);
15373				
15374				jQuery(this).fadeTo(g_options.textpanel_fade_duration,1);
15375			});
15376			
15377		}
15378		
15379	}
15380	
15381	
15382		
15383	
15384	/**
15385	 * position the panel
15386	 */
15387	this.positionPanel = function(customTop, customLeft){
15388		
15389		var objCss = {};
15390		
15391		if(customTop !== undefined && customTop !== null){
15392			objCss.top = customTop;
15393			objCss.bottom = "auto";
15394		}else{
15395			
15396			switch(g_options.textpanel_align){
15397				case "top":
15398					objCss.top = g_options.textpanel_margin + "px";
15399				break;
15400				case "bottom":
15401					objCss.top = "auto";
15402					objCss.bottom = g_options.textpanel_margin + "px";
15403				break;
15404				case "middle":
15405					objCss.top = g_functions.getElementRelativePos(g_objPanel, "middle", g_options.textpanel_margin);
15406				break;
15407			}
15408			
15409		}
15410		
15411		if(customLeft !== undefined && customLeft !== null)
15412			objCss.left = customLeft;
15413			
15414		g_objPanel.css(objCss);
15415	}
15416	
15417	
15418	/**
15419	 * set custom options
15420	 */
15421	this.setOptions = function(objOptions){
15422		
15423		if(g_optionsPrefix)
15424			objOptions = g_functions.convertCustomPrefixOptions(objOptions, g_optionsPrefix, "textpanel");
15425		
15426		g_options = jQuery.extend(g_options, objOptions);
15427				
15428	}
15429	
15430	
15431	/**
15432	 * get html element
15433	 */
15434	this.getElement = function(){
15435		
15436		return(g_objPanel);
15437	}
15438	
15439	/**
15440	 * get element size
15441	 */
15442	this.getSize = function(){
15443		
15444		var objSize = g_functions.getElementSize(g_objPanel);
15445		return(objSize);
15446	}
15447	
15448	
15449	/**
15450	 * refresh panel size, position and contents
15451	 */
15452	this.refresh = function(toShow, noPosition, panelWidth, panelHeight){
15453		
15454		setCss();
15455		
15456		if(!panelWidth)
15457			t.setSizeByParent();
15458		else
15459			t.setPanelSize(panelWidth, panelHeight);
15460		
15461		t.positionElements(false);
15462		
15463		if(noPosition !== true)
15464			t.positionPanel();
15465		
15466		if(toShow === true)
15467			t.show();		
15468	}
15469	
15470	
15471	/**
15472	 * hide the panel
15473	 */
15474	this.hide = function(){
15475		
15476		g_objPanel.hide();
15477	}
15478	
15479	/**
15480	 * show the panel
15481	 */
15482	this.show = function(){
15483		g_objPanel.show();
15484	}
15485	
15486	/**
15487	 * get options
15488	 */
15489	this.getOptions = function(){
15490		return(g_options);
15491	}
15492	
15493	/**
15494	 * get text panel option
15495	 */
15496	this.getOption = function(optionName){
15497		
15498		if(g_options.hasOwnProperty(optionName) == false)
15499			return(null);
15500		
15501		return(g_options[optionName]);
15502	}
15503	
15504	
15505}
15506
15507/** -------------- UGZoomButtonsPanel class ---------------------*/
15508
15509/**
15510 * zoom buttons panel class
15511 */
15512function UGZoomButtonsPanel(){
15513	
15514	var t = this;
15515	var g_objPanel, g_objParent, g_objButtonPlus, g_objButtonMinus, g_objButtonReturn;
15516	var g_slider = new UGSlider;
15517	var g_functions = new UGFunctions();
15518	
15519	var g_options = {
15520		slider_zoompanel_skin: ""		//skin of the zoom panel, if empty inherit from gallery skin
15521	};
15522	
15523	var g_temp = {
15524		
15525	};
15526	
15527	
15528	/**
15529	 * init the panel
15530	 */
15531	this.init = function(objSlider, customOptions){
15532		
15533		g_slider = objSlider;
15534		
15535		if(customOptions)
15536			g_options = jQuery.extend(g_options, customOptions);		
15537	}
15538	
15539	
15540	/**
15541	 * append the bullets html to some parent
15542	 */
15543	this.appendHTML = function(objParent){
15544		g_objParent = objParent;
15545		
15546		var html = "<div class='ug-slider-control ug-zoompanel ug-skin-"+g_options.slider_zoompanel_skin+"'>";
15547		
15548			html += "<div class='ug-zoompanel-button ug-zoompanel-plus'></div>";
15549			html += "<div class='ug-zoompanel-button ug-zoompanel-minus ug-zoompanel-button-disabled'></div>";
15550			html += "<div class='ug-zoompanel-button ug-zoompanel-return ug-zoompanel-button-disabled'></div>";
15551		
15552		html += "</div>";
15553		
15554		objParent.append(html);
15555		
15556		g_objPanel = objParent.children(".ug-zoompanel");
15557		g_objButtonPlus = g_objPanel.children(".ug-zoompanel-plus");
15558		g_objButtonMinus = g_objPanel.children(".ug-zoompanel-minus");
15559		g_objButtonReturn = g_objPanel.children(".ug-zoompanel-return");
15560		
15561	}
15562	
15563	
15564	/**
15565	 * set objects - use it instead insert html
15566	 */
15567	this.setObjects = function(objButtonPlus, objButtonMinus, objButtonReturn){
15568		
15569		g_objButtonPlus = objButtonPlus;
15570		g_objButtonMinus = objButtonMinus;
15571		g_objButtonReturn = objButtonReturn;
15572		
15573		if(g_objButtonMinus)
15574			g_objButtonMinus.addClass("ug-zoompanel-button-disabled");
15575		
15576		if(g_objButtonReturn)
15577			g_objButtonReturn.addClass("ug-zoompanel-button-disabled");
15578			
15579	}
15580	
15581	
15582	/**
15583	 * get buttons element
15584	*/
15585	this.getElement = function(){
15586		
15587		return(g_objPanel);
15588	}
15589	
15590	
15591	/**
15592	 * check if the button disabled
15593	 */
15594	function isButtonDisabled(objButton){
15595		
15596		if(!objButton)
15597			return(true);
15598		
15599		if(objButton.hasClass("ug-zoompanel-button-disabled"))
15600			return(true);
15601		
15602		return(false);
15603	}
15604	
15605	
15606	/**
15607	 * disable some button
15608	 */
15609	function disableButton(objButton){
15610		
15611		if(objButton)
15612			objButton.addClass("ug-zoompanel-button-disabled");
15613	}
15614	
15615	/**
15616	 * enable some button
15617	 */
15618	function enableButton(objButton){
15619		
15620		if(objButton)
15621			objButton.removeClass("ug-zoompanel-button-disabled");		
15622	}
15623	
15624	
15625	/**
15626	 * on zoom change
15627	 */
15628	function onZoomChange(){
15629		
15630		//skip not image types
15631		if(g_slider.isCurrentSlideType("image") == false)
15632			return(true);
15633		
15634		var isFit = g_slider.isCurrentSlideImageFit();
15635		
15636		if(isFit == true){		//if fit, disable buttons
15637			
15638			if(isButtonDisabled(g_objButtonMinus) == false){			
15639				disableButton(g_objButtonMinus);
15640				disableButton(g_objButtonReturn);
15641			}
15642			
15643		}else{	//if not fit, enable minus buttons
15644			
15645			if(isButtonDisabled(g_objButtonMinus) == true){
15646				enableButton(g_objButtonMinus);
15647				enableButton(g_objButtonReturn);				
15648			}
15649			
15650		}
15651			
15652	}
15653	
15654	/**
15655	 * init zoompanel events
15656	 */
15657	t.initEvents = function(){
15658		
15659		//add hover class on buttons
15660		g_functions.addClassOnHover(g_objButtonPlus, "ug-button-hover");
15661		g_functions.addClassOnHover(g_objButtonMinus, "ug-button-hover");
15662		g_functions.addClassOnHover(g_objButtonReturn, "ug-button-hover");
15663		
15664		//set buttons click events
15665		
15666		g_functions.setButtonOnClick(g_objButtonPlus, function(){
15667			
15668			if(isButtonDisabled(g_objButtonPlus) == true)
15669				return(true);
15670			
15671			g_slider.zoomIn();
15672		});
15673		
15674		g_functions.setButtonOnClick(g_objButtonMinus, function(){
15675			
15676			if(isButtonDisabled(g_objButtonMinus) == true)
15677				return(true);
15678			
15679			g_slider.zoomOut();
15680		});
15681		
15682		g_functions.setButtonOnClick(g_objButtonReturn, function(){
15683			
15684			if(isButtonDisabled(g_objButtonReturn) == true)
15685				return(true);
15686			
15687			g_slider.zoomBack();
15688		});
15689				
15690		//on zoom change event
15691		jQuery(g_slider).on(g_slider.events.ZOOM_CHANGE,onZoomChange);
15692		jQuery(g_slider).on(g_slider.events.ITEM_CHANGED,onZoomChange);
15693	
15694	}
15695	
15696	
15697}
15698
15699
15700/** -------------- UgBullets class ---------------------*/
15701
15702function UGBullets(){
15703	
15704	var t = this, g_numBullets = 0, g_gallery = new UniteGalleryMain();
15705	var g_objBullets, g_objParent, g_activeIndex = -1, g_bulletWidth;
15706	var g_functions = new UGFunctions();
15707	
15708	var g_temp = {
15709		isInited:false
15710	};
15711	
15712	var g_options = {
15713		bullets_skin: "",					//bullets_skin: ""		//skin of the bullets, if empty inherit from gallery skin
15714		bullets_addclass: "",					//bullets object class addition
15715		bullets_space_between:-1			//set the space between bullets. If -1 then will be set default space from the skins
15716	}
15717	
15718	
15719	/**
15720	 * the events
15721	 */
15722	this.events = {
15723		BULLET_CLICK : "bullet_click"
15724	};
15725	
15726	/**
15727	 * init the bullets
15728	 */
15729	this.init = function(gallery, customOptions, numBullets){
15730		g_gallery = gallery;
15731		
15732		if(numBullets)
15733			g_numBullets = numBullets;
15734		else	
15735			g_numBullets = g_gallery.getNumItems();
15736		
15737		g_temp.isInited = true;
15738		g_options = jQuery.extend(g_options, customOptions);
15739		
15740		if(g_options.bullets_skin == "")
15741			g_options.bullets_skin = g_options.gallery_skin;
15742		
15743	}
15744	
15745	/**
15746	 * add bullets to the html
15747	 */
15748	function setHtmlBullets(){
15749		var html = "";
15750		
15751		var addHtml = "";
15752		if(g_options.bullets_space_between != -1)
15753			addHtml = " style='margin-left:" + g_options.bullets_space_between + "px'";
15754		
15755		for(var i=0; i< g_numBullets; i++){
15756			if(i == 0)
15757				html += "<div class='ug-bullet'></div>";
15758			else
15759				html += "<div class='ug-bullet'"+addHtml+"></div>";
15760		}
15761		
15762		g_objBullets.html(html);
15763		
15764		//set bullet width value
15765		if(!g_bulletWidth){
15766			var objBullet = g_objBullets.find(".ug-bullet:first-child");
15767			if(objBullet.length)
15768				g_bulletWidth = objBullet.width();
15769		}
15770	}
15771
15772	/**
15773	 * get total bullets width
15774	 */
15775	this.getBulletsWidth = function(){
15776		if(g_numBullets == 0)
15777			return(0);
15778		
15779		if(!g_bulletWidth)
15780			return(0);
15781		
15782		var totalWidth = g_numBullets*g_bulletWidth+(g_numBullets-1)*g_options.bullets_space_between;
15783		return(totalWidth);
15784	}
15785	
15786	
15787	/**
15788	 * append the bullets html to some parent
15789	 */
15790	this.appendHTML = function(objParent){
15791		g_objParent = objParent;
15792		
15793		validateInited();
15794		var addClass = "";
15795		if(g_options.bullets_addclass != "")
15796			addClass = " " + g_options.bullets_addclass;
15797			
15798		var html = "<div class='ug-slider-control ug-bullets ug-skin-"+g_options.bullets_skin + addClass+"'>";
15799		
15800		html += "</div>";
15801		
15802		g_objBullets = jQuery(html);
15803		
15804		objParent.append(g_objBullets);
15805		
15806		setHtmlBullets();
15807		
15808		initEvents();
15809	}	
15810	
15811	
15812	/**
15813	 * update number of bullets
15814	 */
15815	this.updateNumBullets = function(numBullets){
15816		
15817		g_numBullets = numBullets;
15818		setHtmlBullets();
15819		initEvents();
15820	}
15821	
15822	
15823	/**
15824	 * 
15825	 * on bullet click
15826	 */
15827	function onBulletClick(objBullet){
15828				
15829		//filter not active only
15830		if(t.isActive(objBullet) == true)
15831			return(true);
15832		
15833		var index = objBullet.index();
15834			
15835		jQuery(t).trigger(t.events.BULLET_CLICK, index);
15836	}
15837	
15838	
15839	/**
15840	 * init the bullets events
15841	 * trigger bullet click event
15842	 */
15843	function initEvents(){
15844		
15845		var objBullets = g_objBullets.children(".ug-bullet");
15846		
15847		g_functions.setButtonOnClick(objBullets, onBulletClick);
15848		
15849		objBullets.on("mousedown mouseup",function(event){
15850			//event.preventDefault();
15851			return(false);
15852		});
15853		
15854	}
15855	
15856	
15857	/**
15858	 * get the bullets element
15859	 */
15860	this.getElement = function(){
15861		return g_objBullets;
15862	}
15863	
15864	
15865	/**
15866	 * set some item active
15867	 */
15868	this.setActive = function(index){
15869		validateInited();
15870		validateIndex(index);
15871		
15872		var children = g_objBullets.children(".ug-bullet");
15873		children.removeClass("ug-bullet-active");
15874		
15875		var bullet = jQuery(children[index]);
15876		bullet.addClass("ug-bullet-active");
15877		
15878		g_activeIndex = index;
15879	}
15880
15881	
15882	/**
15883	 * check if the bullet is active
15884	 */
15885	this.isActive = function(index){
15886		validateIndex(index);
15887		
15888		if(typeof index != "number")
15889			var objBullet = index;
15890		else{
15891			var objBullet = g_objBullets.children(".ug-bullet")[index];			
15892		}
15893		
15894		if(objBullet.hasClass("ug-bullet-active"))
15895				return(true);
15896		
15897		return(false);
15898	}
15899	
15900	
15901	/**
15902	 * get bullets number
15903	 */
15904	this.getNumBullets = function(){
15905		return(g_numBullets);
15906	}
15907	
15908	/**
15909	 * validate bullets index
15910	 */
15911	function validateIndex(index){
15912		if(index < 0 || index >= g_numBullets)
15913			throw new Error("wrong bullet index: " + index);
15914	}
15915	
15916	
15917	/**
15918	 * validate that the bullets are inited
15919	 */
15920	function validateInited(){
15921		
15922		if(g_temp.isInited == true)
15923			return(true);
15924		
15925		throw new Error("The bullets are not inited!");
15926	}
15927	
15928	
15929	
15930}
15931
15932/** -------------- UgProgressBar class ---------------------*/
15933
15934function UGProgressBar(){
15935	
15936	var t = this, g_isInited = false;
15937	var g_percent = 0, g_objBar, g_objInner, g_functions = new UGFunctions();
15938	
15939	var g_options = {
15940		slider_progressbar_color:"#ffffff",			//progress bar color
15941		slider_progressbar_opacity: 0.6,			//progress bar opacity
15942		slider_progressbar_line_width: 5			//progress bar line width
15943	}
15944	
15945	
15946	/**
15947	 * put progress pie to some wrapper
15948	 */
15949	this.put = function(g_objWrapper, userOptions){
15950		
15951		if(userOptions)
15952			g_options = jQuery.extend(g_options, userOptions);
15953		
15954		g_objWrapper.append("<div class='ug-progress-bar'><div class='ug-progress-bar-inner'></div></div>");
15955		g_objBar = g_objWrapper.children(".ug-progress-bar");
15956		g_objInner = g_objBar.children(".ug-progress-bar-inner");
15957		
15958		//init the objects
15959		g_objInner.css("background-color", g_options.slider_progressbar_color);
15960		g_objBar.height(g_options.slider_progressbar_line_width);
15961		g_objInner.height(g_options.slider_progressbar_line_width);
15962		g_objInner.width("0%");
15963		
15964		//set opacity old way (because ie bug)
15965		var opacity = g_options.slider_progressbar_opacity;
15966		
15967		var objInnerHTML = g_objInner[0];
15968		objInnerHTML.style.opacity = opacity;
15969		objInnerHTML.style.filter = 'alpha(opacity=' + opacity*100 + ')';
15970	}
15971	
15972	
15973	/**
15974	 * put the pie hidden
15975	 */
15976	this.putHidden = function(g_objWrapper, userOptions){
15977		t.put(g_objWrapper, userOptions);
15978		g_objBar.hide();
15979	}
15980	
15981	/**
15982	 * get the bar object
15983	 */
15984	this.getElement = function(){
15985		
15986		return(g_objBar);
15987	}
15988	
15989	/**
15990	 * set progress bar size
15991	 */
15992	this.setSize = function(width){
15993		
15994		g_objBar.width(width);
15995		g_objInner.width(width);
15996		t.draw();
15997	}
15998	
15999	
16000	/**
16001	 * set position
16002	 */
16003	this.setPosition = function(left, top, offsetLeft, offsetTop){
16004		
16005		g_functions.placeElement(g_objBar, left, top, offsetLeft, offsetTop);
16006	}
16007	
16008	
16009	/**
16010	 * draw the progress bar
16011	 */
16012	this.draw = function(){
16013		var innerWidth = g_percent * 100;
16014		
16015		g_objInner.width(innerWidth + "%");
16016	}
16017	
16018	
16019	/**
16020	 * set and draw the progress
16021	 */
16022	this.setProgress = function(percent){
16023		
16024		g_percent = g_functions.normalizePercent(percent);
16025		
16026		//debugLine(g_percent, true);
16027		
16028		t.draw();
16029	}
16030	
16031	/**
16032	 * get type string
16033	 */
16034	this.getType = function(){
16035		return("bar");
16036	}
16037	
16038}
16039
16040/** -------------- UgProgressPie class ---------------------*/
16041
16042function UGProgressPie(){
16043	
16044	var t = this, g_isInited = false;
16045	var g_percent, g_objPie, g_functions = new UGFunctions();
16046	
16047	var g_options = {
16048		slider_progresspie_type_fill: false,		//false is stroke, true is fill - the progress pie type, stroke of fill
16049		slider_progresspie_color1: "#B5B5B5", 		//the first color of the progress pie
16050		slider_progresspie_color2: "#E5E5E5",		//progress pie second color 
16051		slider_progresspie_stroke_width: 6,			//progress pie stroke width 
16052		slider_progresspie_width: 30,				//progess pie width
16053		slider_progresspie_height:30				//progress pie height
16054	}
16055	
16056	
16057	/**
16058	 * put progress pie to some wrapper
16059	 */
16060	this.put = function(g_objWrapper, userOptions){
16061		
16062		if(userOptions)
16063			g_options = jQuery.extend(g_options, userOptions);
16064			
16065		g_objWrapper.append("<canvas class='ug-canvas-pie' width='"+g_options.slider_progresspie_width+"' height='"+g_options.slider_progresspie_height+"'></canvas>");
16066		g_objPie = g_objWrapper.children(".ug-canvas-pie");
16067	}
16068	
16069	
16070	/**
16071	 * put the pie hidden
16072	 */
16073	this.putHidden = function(g_objWrapper, userOptions){
16074		t.put(g_objWrapper, userOptions);
16075		draw(0.1);
16076		g_objPie.hide();
16077	}
16078	
16079	
16080	/**
16081	 * get jquery object
16082	 */
16083	this.getElement = function(){
16084		return(g_objPie);
16085	}
16086	
16087	/**
16088	 * set position
16089	 */
16090	this.setPosition = function(left, top){
16091		
16092		g_functions.placeElement(g_objPie, left, top);
16093		
16094	}
16095	
16096	/**
16097	 * get the height and width of the object
16098	 */
16099	this.getSize = function(){
16100		
16101		var obj = {
16102			width: g_options.slider_progresspie_width,
16103			height: g_options.slider_progresspie_height
16104		};
16105		
16106		return(obj);
16107	}	
16108	
16109	/**
16110	 * draw the progress pie
16111	 */
16112	function draw(percent){
16113		
16114		if(!percent)
16115			var percent = 0;
16116		
16117		var radius = Math.min(g_options.slider_progresspie_width, g_options.slider_progresspie_height) / 2;
16118		
16119		var ctx = g_objPie[0].getContext('2d');
16120		
16121		//init the context
16122		if(g_isInited == false){
16123			
16124			g_isInited = true;
16125			
16126			ctx.rotate(Math.PI*(3/2));
16127			ctx.translate(-2 * radius,0);
16128		}		
16129		
16130		ctx.clearRect(0,0,g_options.slider_progresspie_width, g_options.slider_progresspie_height);
16131		
16132		var centerX = g_options.slider_progresspie_width / 2;
16133		var centerY = g_options.slider_progresspie_height / 2;
16134	    
16135		//draw main arc
16136		var startPoint = 0;
16137		var endPoint = percent * Math.PI * 2;
16138				
16139	    
16140		if(g_options.slider_progresspie_type_fill == true){		//fill
16141			
16142			ctx.beginPath();
16143				ctx.moveTo(centerX, centerY); 
16144			    ctx.arc(centerX,centerY,radius,startPoint, endPoint);
16145			    ctx.lineTo(centerX, centerY); 
16146			    
16147			    ctx.fillStyle = g_options.slider_progresspie_color1;
16148			    ctx.fill();
16149		    ctx.closePath();
16150		    
16151		}else{		//stroke
16152		    ctx.globalCompositeOperation = "source-over";
16153			
16154			ctx.beginPath();
16155				ctx.moveTo(centerX, centerY); 
16156			    ctx.arc(centerX,centerY,radius,startPoint, endPoint);
16157			    ctx.lineTo(centerX, centerY); 
16158			    
16159			    ctx.fillStyle = g_options.slider_progresspie_color1;
16160			    ctx.fill();
16161			ctx.closePath();
16162		    
16163		    ctx.globalCompositeOperation = "destination-out";
16164			
16165			var radius2 = radius - g_options.slider_progresspie_stroke_width;
16166		    
16167			ctx.beginPath();
16168								
16169				ctx.moveTo(centerX, centerY); 
16170			    ctx.arc(centerX,centerY,radius2,startPoint, endPoint);
16171			    ctx.lineTo(centerX, centerY); 
16172			    
16173			    ctx.fillStyle = g_options.slider_progresspie_color1;
16174			    ctx.fill();
16175			    
16176			ctx.closePath();
16177		}
16178	    
16179	    
16180		//draw rest arc (only on fill type):
16181	    if(g_options.slider_progresspie_type_fill == true){
16182			startPoint = endPoint;
16183			endPoint = Math.PI * 2;
16184			ctx.beginPath();
16185			    ctx.arc(centerX,centerY,radius,startPoint, endPoint);
16186			    ctx.lineTo(centerX, centerY); 
16187		    ctx.fillStyle = g_options.slider_progresspie_color2;
16188		    ctx.fill();
16189		    ctx.closePath();	    	
16190	    }
16191	    
16192	}
16193	
16194	
16195	/**
16196	 * set progress (0-1)
16197	 */
16198	this.setProgress = function(percent){
16199		
16200		percent = g_functions.normalizePercent(percent);
16201		
16202		g_percent = percent;
16203		draw(percent);
16204	}
16205	
16206	/**
16207	 * get type string
16208	 */
16209	this.getType = function(){
16210		return("pie");
16211	}
16212	
16213}
16214
16215/**f
16216 * touch thumbs control class
16217 * addon to strip gallery
16218 */
16219function UGTouchSliderControl(){
16220	
16221	var g_objSlider, g_objInner, g_parent = new UGSlider();
16222	var g_objParent, g_options, t=this;
16223	
16224	var g_functions = new UGFunctions();
16225	
16226	
16227	var g_options = {
16228		  slider_transition_continuedrag_speed: 250,				//the duration of continue dragging after drag end
16229		  slider_transition_continuedrag_easing: "linear",		//easing function of continue dragging animation
16230		  slider_transition_return_speed: 300,					//the duration of the "return to place" animation
16231		  slider_transition_return_easing: "easeInOutQuad"		//easing function of the "return to place" animation
16232	};
16233	
16234	var g_temp = {
16235		touch_active: false,		
16236		startMouseX: 0,		
16237		startMouseY: 0,
16238		lastMouseX: 0,
16239		lastMouseY: 0,
16240		startPosx:0, 
16241		startTime:0,
16242		isInitDataValid:false,
16243		slides: null,
16244		lastNumTouches:0,
16245		isDragging: false,
16246		storedEventID: "touchSlider",
16247		videoStartX: 0,
16248		isDragVideo: false,
16249		videoObject: null
16250	};
16251	
16252	
16253	/**
16254	 * get diff inner object position from current item pos
16255	 */
16256	function getDiffPosFromCurrentItem(slides){
16257		
16258		if(!slides)
16259			var slides = g_parent.getSlidesReference();
16260		
16261		var posCurrent = g_functions.getElementSize(slides.objCurrentSlide);
16262		var inPlaceX = -posCurrent.left;
16263		var objInnerSize = g_functions.getElementSize(g_objInner);
16264		var diffPos = inPlaceX - objInnerSize.left;
16265		
16266		return(diffPos);
16267	}
16268	
16269	/**
16270	 * check if the movement that was held is valid for slide change
16271	 */
16272	function isMovementValidForChange(){
16273		
16274		var slides = g_parent.getSlidesReference();
16275
16276		//check position, if more then half, move
16277		var diffPos = getDiffPosFromCurrentItem(slides);
16278		
16279		var breakSize = Math.round(slides.objCurrentSlide.width() * 3 / 8);
16280				
16281		if(Math.abs(diffPos) >= breakSize)
16282			return(true);
16283				
16284		//check gesture, if vertical mostly then not move
16285		var diffX = Math.abs(g_temp.lastMouseX - g_temp.startMouseX);
16286		var diffY = Math.abs(g_temp.lastMouseY - g_temp.startMouseY);
16287		
16288		//debugLine("diffx: " + diffX, true, true);
16289		
16290		if(diffX < 20)
16291			return(false);
16292		
16293		//if(diffY >= diffX)
16294			//return(false);
16295				
16296		//check time. Short time always move
16297		var endTime = jQuery.now();
16298		var diffTime = endTime - g_temp.startTime;
16299		
16300		//debugLine("time: " + diffTime, true);
16301		
16302		if(diffTime < 500)
16303			return(true);
16304		
16305					
16306		return(false);
16307	}
16308
16309	/**
16310	 * check tab event occured
16311	 * invokes on touchend event on the slider object
16312	 */
16313	this.isTapEventOccured = function(event){
16314		
16315		//validate one touch
16316		var arrTouches = g_functions.getArrTouches(event);
16317		var numTouches = arrTouches.length;
16318			
16319		if(numTouches != 0 || g_temp.lastNumTouches != 0){
16320			g_temp.lastNumTouches = numTouches;
16321			return(false);
16322		}
16323			
16324		g_temp.lastNumTouches = numTouches;
16325				
16326		var slides = g_parent.getSlidesReference();
16327
16328		//check position, if more then half, move
16329		var diffPos = getDiffPosFromCurrentItem(slides);
16330		
16331		//check gesture, if vertical mostly then not move
16332		var diffX = Math.abs(g_temp.lastMouseX - g_temp.startMouseX);
16333		var diffY = Math.abs(g_temp.lastMouseY - g_temp.startMouseY);
16334		
16335		//check by time
16336		var endTime = jQuery.now();
16337		var diffTime = endTime - g_temp.startTime;
16338		
16339		//combine move and time
16340		if(diffX < 20 && diffY < 50 && diffTime < 500)
16341			return(true);
16342		
16343		return(false);
16344	}
16345	
16346	/**
16347	 * return the item to place
16348	 */
16349	function returnToPlace(slides){
16350		
16351		if(g_parent.isInnerInPlace() == true)
16352			return(false);
16353						
16354		//trigger before return event
16355		g_objParent.trigger(g_parent.events.BEFORE_RETURN);
16356		
16357		if(!slides)
16358			var slides = g_parent.getSlidesReference();
16359		
16360		var posCurrent = g_functions.getElementSize(slides.objCurrentSlide);
16361		var destX = -posCurrent.left;
16362				
16363		//animate objects		
16364		g_objInner.animate({left:destX+"px"},{
16365			duration: g_options.slider_transition_return_speed,
16366			easing: g_options.slider_transition_continuedrag_easing,
16367			queue: false,
16368			progress: function(animation, number, remainingMS){
16369								
16370				//check drag video
16371				if(g_temp.isDragVideo == true){
16372					var objSize = g_functions.getElementSize(g_objInner);
16373					var innerX = objSize.left;
16374					
16375					var posDiff = innerX - destX;
16376					
16377					var videoPosX = g_temp.videoStartX + posDiff;
16378					g_temp.videoObject.css("left", videoPosX);
16379				}
16380				
16381			},
16382			complete: function(){
16383				g_objParent.trigger(g_parent.events.AFTER_RETURN);
16384			}
16385		});
16386		
16387	}
16388	
16389	
16390	/**
16391	 * 
16392	 * change the item to given direction
16393	 */
16394	function changeItem(direction){
16395		
16396		g_parent.getVideoObject().hide();
16397		g_parent.switchSlideNums(direction);
16398		g_parent.placeNabourItems();
16399
16400	}
16401	
16402	/**
16403	 * continue the dragging by changing the slides to the right place.
16404	 */
16405	function continueSlideDragChange(){
16406		
16407		//get data
16408		var slides = g_parent.getSlidesReference();
16409		
16410		var diffPos = getDiffPosFromCurrentItem(slides);
16411		
16412		if(diffPos == 0)
16413			return(false);
16414		
16415		var direction = (diffPos > 0) ? "left" : "right";
16416			
16417		var isReturn = false;
16418			
16419		switch(direction){
16420			case "right":	//change to prev item
16421				
16422				if( g_parent.isSlideHasItem(slides.objPrevSlide) ){
16423					
16424					var posPrev = g_functions.getElementSize(slides.objPrevSlide);
16425					var destX = -posPrev.left;
16426					
16427				}else	//return current item
16428					isReturn = true;
16429				
16430			break;	
16431			case "left":		//change to next item
16432				
16433				if( g_parent.isSlideHasItem(slides.objNextSlide) ){
16434					
16435					var posNext = g_functions.getElementSize(slides.objNextSlide);
16436					var destX = -posNext.left;
16437					
16438				}else					
16439					isReturn = true;				
16440			break;
16441	   }
16442		
16443		
16444		if(isReturn == true){
16445			returnToPlace(slides);
16446			
16447		}else{
16448						
16449			//animate objects
16450			g_objInner.stop().animate({left:destX+"px"},{
16451				duration: g_options.slider_transition_continuedrag_speed,
16452				easing: g_options.slider_transition_continuedrag_easing,
16453				queue: false,
16454				progress: function(){
16455					
16456					//check drag video
16457					if(g_temp.isDragVideo == true){
16458						var objSize = g_functions.getElementSize(g_objInner);
16459						var innerX = objSize.left;
16460						var posDiff = innerX - g_temp.startPosx;
16461						var videoPosX = g_temp.videoStartX + posDiff;
16462						g_temp.videoObject.css("left", videoPosX);
16463					}
16464					
16465				},
16466				always:function(){
16467					changeItem(direction);
16468					g_objParent.trigger(g_parent.events.AFTER_DRAG_CHANGE);
16469				}
16470			});
16471			
16472		}
16473				
16474		
16475	}
16476
16477	
16478	/**
16479	 * handle slider drag on mouse drag
16480	 */
16481	function handleSliderDrag(event){
16482		
16483		var diff = g_temp.lastMouseX - g_temp.startMouseX;
16484		
16485		if(diff == 0)
16486			return(true);
16487		
16488		var direction = (diff < 0) ? "left":"right";
16489		
16490		var objZoomSlider = g_parent.getObjZoom();
16491		
16492		//don't drag if the zoom panning enabled
16493		//store init position after image zoom pan end
16494		if(objZoomSlider){
16495			
16496			var isPanEnabled = objZoomSlider.isPanEnabled(event,direction);
16497						
16498			if(isPanEnabled == true){
16499				g_temp.isInitDataValid = false;
16500				return(true);				
16501			}else{
16502				
16503				if(g_temp.isInitDataValid == false){
16504					storeInitTouchData(event);
16505					return(true);
16506				}
16507				
16508			}
16509		}
16510		
16511		//set inner div position
16512		var currentPosx = g_temp.startPosx + diff;
16513		
16514		//check out of borders and slow down the motion:
16515		if(diff > 0 && currentPosx > 0)
16516			currentPosx = currentPosx / 3;		
16517		
16518		else if(diff < 0 ){
16519			
16520			var innerEnd = currentPosx + g_objInner.width();
16521			var sliderWidth = g_objSlider.width();
16522			
16523			if( innerEnd <  sliderWidth ){
16524				currentPosx = g_temp.startPosx + diff/3;
16525			}
16526		}
16527		
16528		if(g_temp.isDragging == false){
16529			g_temp.isDragging = true;
16530			g_objParent.trigger(g_parent.events.START_DRAG);
16531		}
16532				
16533		g_objInner.css("left", currentPosx+"px");
16534		
16535		//drag video
16536		if(g_temp.isDragVideo == true){
16537			var posDiff = currentPosx - g_temp.startPosx;
16538			var videoPosX = g_temp.videoStartX + posDiff;
16539			
16540			g_temp.videoObject.css("left", videoPosX);
16541		}
16542		
16543	}
16544	
16545	/**
16546	 * store init touch position
16547	 */
16548	function storeInitTouchData(event){
16549		
16550		var mousePos = g_functions.getMousePosition(event);
16551		
16552		g_temp.startMouseX = mousePos.pageX;
16553		
16554		//debugLine("startx:" + g_temp.startMouseX, true, true);
16555		
16556		g_temp.startMouseY = mousePos.pageY;
16557		
16558		g_temp.lastMouseX = g_temp.startMouseX;
16559		g_temp.lastMouseY = g_temp.startMouseY;
16560		g_temp.startTime = jQuery.now();
16561		
16562		var arrTouches = g_functions.getArrTouches(event);		
16563		g_temp.startArrTouches = g_functions.getArrTouchPositions(arrTouches);
16564		
16565		var objPos = g_functions.getElementSize(g_objInner);
16566		
16567		g_temp.startPosx = objPos.left;
16568		
16569		g_temp.isInitDataValid = true;
16570		
16571		//check if video object need to be dragged
16572		g_temp.isDragVideo = false;
16573					
16574		
16575		g_functions.storeEventData(event, g_temp.storedEventID);
16576	}
16577	
16578	/**
16579	 * disable touch active
16580	 */
16581	function disableTouchActive(who){
16582		
16583		g_temp.touch_active = false;
16584		
16585		//debugLine("disable: " + who, true, true);
16586	}
16587	
16588	/**
16589	 * enable the touch active
16590	 */
16591	function enableTouchActive(who, event){
16592		
16593		g_temp.touch_active = true;
16594		storeInitTouchData(event);
16595		
16596		//debugLine("enable: " + who, true, true);
16597	}
16598
16599	
16600	/**
16601	 * on touch slide start
16602	 * 
16603	 */
16604	function onTouchStart(event){
16605		
16606		event.preventDefault();
16607		
16608		g_temp.isDragging = false;
16609		
16610		//debugLine("touchstart", true, true);
16611		
16612		//check if the slides are changing from another event.
16613		if(g_parent.isAnimating() == true){
16614			g_objInner.stop(true, true);
16615		}
16616		
16617		//check num touches
16618		var arrTouches = g_functions.getArrTouches(event);
16619		if(arrTouches.length > 1){
16620			
16621			if(g_temp.touch_active == true){
16622				disableTouchActive("1");
16623			}
16624			
16625			return(true);
16626		}
16627						
16628		if(g_temp.touch_active == true){
16629			return(true);
16630		}
16631		
16632		enableTouchActive("1", event);
16633		
16634	}
16635	
16636
16637	/**
16638	 * 
16639	 * on touch move event
16640	 */
16641	function onTouchMove(event){
16642		
16643		if(g_temp.touch_active == false)
16644			return(true);
16645		
16646		//detect moving without button press
16647		if(event.buttons == 0){
16648			disableTouchActive("2");
16649			
16650			continueSlideDragChange();
16651						
16652			return(true);
16653		}
16654
16655		g_functions.updateStoredEventData(event, g_temp.storedEventID);
16656				
16657		event.preventDefault();
16658		
16659		var mousePos = g_functions.getMousePosition(event);
16660		g_temp.lastMouseX = mousePos.pageX;
16661		g_temp.lastMouseY = mousePos.pageY;
16662				
16663		//debugLine("lastX:" + g_temp.lastMouseX, true, true);
16664		
16665		var scrollDir = null;
16666		
16667		if(g_options.slider_vertical_scroll_ondrag == true)
16668			scrollDir = g_functions.handleScrollTop(g_temp.storedEventID);
16669		
16670		if(scrollDir !== "vert")
16671			handleSliderDrag(event);
16672			
16673	}
16674	
16675	/**
16676	 * on touch end event
16677	 */
16678	function onTouchEnd(event){
16679		
16680		//debugLine("touchend", true, true);
16681		
16682		var arrTouches = g_functions.getArrTouches(event);
16683		var numTouches = arrTouches.length;
16684		var isParentInPlace = g_parent.isInnerInPlace();
16685		
16686		if(isParentInPlace == true && g_temp.touch_active == false && numTouches == 0){
16687			
16688			return(true);
16689		}
16690				
16691		if(numTouches == 0 && g_temp.touch_active == true){
16692											
16693			disableTouchActive("3");
16694			
16695			var isValid = false;
16696			
16697			var wasVerticalScroll = g_functions.wasVerticalScroll(g_temp.storedEventID);
16698			
16699			if(wasVerticalScroll == false)
16700				isValid = isMovementValidForChange();
16701						
16702			if(isValid == true)
16703				continueSlideDragChange();		//change the slide
16704			else
16705				returnToPlace();	//return the inner object to place (if not in place)
16706			
16707		}else{
16708			
16709			if(numTouches == 1 && g_temp.touch_active == false){
16710								
16711				enableTouchActive("2",event);				
16712			}
16713				
16714		}
16715					
16716	}
16717
16718
16719	/**
16720	 * init touch events
16721	 */
16722	function initEvents(){
16723		
16724		//slider mouse down - drag start
16725		g_objSlider.bind("mousedown touchstart",onTouchStart);
16726		
16727		//on body move
16728		jQuery("body").bind("mousemove touchmove",onTouchMove);
16729		
16730		//on body mouse up - drag end
16731		jQuery(window).add("body").bind("mouseup touchend", onTouchEnd);
16732		
16733	}
16734	
16735	
16736	
16737	/**
16738	 * init function for avia controls
16739	 */
16740	this.init = function(objSlider, customOptions){
16741		
16742		g_parent = objSlider;
16743		g_objParent = jQuery(g_parent);
16744		g_objects = objSlider.getObjects();
16745				
16746		g_objSlider = g_objects.g_objSlider;
16747		g_objInner = g_objects.g_objInner;
16748
16749		g_options = jQuery.extend(g_options, customOptions);
16750				
16751		initEvents();
16752	}
16753	
16754	
16755	/**
16756	 * get last mouse position
16757	 */
16758	this.getLastMousePos = function(){
16759		var obj = {
16760			pageX: g_temp.lastMouseX,
16761			pageY: g_temp.lastMouseY
16762		};
16763		
16764		return(obj);
16765	}
16766	
16767	
16768	/**
16769	 * is touch active
16770	 */
16771	this.isTouchActive = function(){
16772		
16773		return(g_temp.touch_active);
16774		
16775	}
16776	
16777	
16778}
16779/**
16780 * touch thumbs control class
16781 * addon to strip gallery
16782 */
16783function UGZoomSliderControl(){
16784	
16785	var g_objSlider, g_objInner, g_parent = new UGSlider(), g_objParent;
16786	
16787	var g_functions = new UGFunctions();
16788	
16789	var t = this;
16790	
16791	var g_options = {
16792		slider_zoom_step: 1.2,							//the step of zooming with mouse wheel or zoom button
16793		slider_zoom_max_ratio: 6,						//max zoom ratio
16794		slider_zoom_return_pan_duration: 400,			//the return from pan animation duration 
16795		slider_zoom_return_pan_easing: "easeOutCubic"	//the return from pan wasing function
16796	};
16797	
16798	var g_temp = {
16799		isPanActive:false,
16800		startMouseX:0,
16801		startMouseY:0,
16802		lastMouseX:0,
16803		lastMouseY:0,
16804		startImageX:0,
16805		startImageY:0,
16806		panXActive:false,
16807		panYActive:false,
16808		objImage:null,
16809		objImageSize:null,
16810		objParent:null,
16811		objParentSize:null,
16812		objSlide:null,
16813		storeImageLastTime:0,
16814		
16815		isZoomActive: false,
16816		startDistance:0,
16817		startMiddlePoint:null,
16818		imageOrientPoint:null,
16819		objFitImageSize:null,
16820		isZoomedOnce:false
16821	};
16822
16823	
16824	/**
16825	 * init the object
16826	 */
16827	function initObject(objSlider, customOptions){
16828		
16829		g_parent = objSlider;
16830		g_objParent = jQuery(g_parent);
16831		g_objects = objSlider.getObjects();
16832		g_objSlider = g_objects.g_objSlider;
16833		g_objInner = g_objects.g_objInner;
16834		
16835		g_options = jQuery.extend(g_options, customOptions);
16836				
16837		initEvents();
16838	}
16839	
16840	
16841	/**
16842	 * get fit image to slider scale mode
16843	 * the fill become fit
16844	 */
16845	function getFitScaleMode(){
16846		
16847		var scaleMode = g_parent.getScaleMode();
16848		
16849		if(scaleMode != "down")
16850			scaleMode = "fit";
16851		
16852		return(scaleMode);
16853	}
16854	
16855	
16856	/**
16857	 * cache current slide and image
16858	 */
16859	function storeCurrentImage(){		
16860		
16861		//prevent continious image storring
16862		var currentTime = jQuery.now();
16863		var diff = currentTime - g_temp.storeImageLastTime;
16864		
16865		if(diff < 20)
16866			return(false);
16867		
16868		var slides = g_parent.getSlidesReference();
16869		g_temp.objSlide = slides.objCurrentSlide;
16870		g_temp.objImage = slides.objCurrentSlide.find("img");
16871		
16872		if(g_temp.objImage.length == 0)
16873			return(false);
16874			
16875		g_temp.objImageSize = g_functions.getElementSize(g_temp.objImage);
16876		g_temp.objParent = g_temp.objImage.parent();
16877		g_temp.objParentSize = g_functions.getElementSize(g_temp.objParent);
16878		
16879		var scaleMode = getFitScaleMode();
16880		
16881		objPadding = g_parent.getObjImagePadding();
16882		
16883		g_temp.objFitImageSize = g_functions.getImageInsideParentDataByImage(g_temp.objImage, scaleMode, objPadding);
16884		
16885		var currentTime = jQuery.now();
16886		g_temp.storeImageLastTime = currentTime;
16887		
16888		return(true);
16889	}
16890	
16891	
16892	/**
16893	 * zoom current image
16894	 * mode: in, out, back
16895	 */
16896	function zoomCurrentImage(mode, mousePos){
16897		
16898		var slides = g_parent.getSlidesReference();
16899		var objImage = slides.objCurrentSlide.find("img");
16900		var scaleMode = getFitScaleMode();
16901		
16902		g_objParent.trigger(g_parent.events.ZOOM_START);
16903		
16904		//flag if the images zoomed
16905		var isZoomed = true;
16906		
16907		var objPadding = g_parent.getObjImagePadding();
16908				
16909		if(mode == "back"){	
16910			var objOriginalSize = g_functions.getImageOriginalSize(objImage);
16911			g_functions.scaleImageFitParent(objImage, objOriginalSize.width, objOriginalSize.height, scaleMode, objPadding);
16912		}
16913		else{			
16914			var zoomIn = (mode == "in")?true:false;
16915			
16916			isZoomed = g_functions.zoomImageInsideParent(objImage, zoomIn, g_options.slider_zoom_step, mousePos, scaleMode, g_options.slider_zoom_max_ratio, objPadding);
16917		}
16918		
16919		if(isZoomed == true){
16920			g_objParent.trigger(g_parent.events.ZOOMING);
16921			g_objParent.trigger(g_parent.events.ZOOM_CHANGE);
16922			g_objParent.trigger(g_parent.events.ZOOM_END);
16923		}
16924		
16925	}
16926	
16927	
16928	function ____________PAN_____________(){};
16929	
16930	
16931	/**
16932	 * check if pan is posible for the current image
16933	 * check if the image is bigger then the parent
16934	 */
16935	function isPanPosible(objImage, event, stictTouchesCheck){
16936		
16937		//check num touches, strict means that even if 0 - pan not posible
16938		var arrTouches = g_functions.getArrTouches(event);
16939		
16940		if(stictTouchesCheck === true){
16941			
16942			if(arrTouches.length != 1)
16943				return(false);			
16944		}else{
16945			if(arrTouches.length > 1)
16946				return(false);			
16947		}
16948		
16949		if(g_functions.isElementBiggerThenParent(objImage))
16950			return(true);
16951		
16952		return(false);
16953	}
16954	
16955	
16956	/**
16957	 * store pan values
16958	 */
16959	function storePanInitValues(event){
16960		
16961		var mousePos = g_functions.getMousePosition(event);
16962		
16963		g_temp.startMouseX = mousePos.pageX;
16964		g_temp.startMouseY = mousePos.pageY;
16965		
16966		g_temp.lastMouseX = g_temp.startMouseX;
16967		g_temp.lastMouseY = g_temp.startMouseY;
16968		
16969		g_temp.startImageX = g_temp.objImageSize.left;
16970		g_temp.startImageY = g_temp.objImageSize.top;
16971		
16972		g_temp.panXActive = (g_temp.objImageSize.width > g_temp.objParentSize.width);
16973		g_temp.panYActive = (g_temp.objImageSize.height > g_temp.objParentSize.height);
16974		
16975	}
16976	
16977	
16978	/**
16979	 * check pan start, and start if posible
16980	 */
16981	function startPan(event){
16982				
16983		g_temp.isPanActive = true;
16984		storePanInitValues(event);
16985		
16986	}
16987	
16988	
16989	/**
16990	 * pan the image
16991	 */
16992	function panImage(event){
16993		
16994		if(g_temp.objImage == undefined || g_temp.objImage.length == 0)
16995			return(true);
16996		
16997		var mousePos = g_functions.getMousePosition(event);
16998		
16999		var diffX = mousePos.pageX - g_temp.startMouseX;
17000		var diffY = mousePos.pageY - g_temp.startMouseY;
17001		
17002		//get active direction
17003		var diffLastX = mousePos.pageX - g_temp.lastMouseX;
17004		var diffLastY = mousePos.pageY - g_temp.lastMouseY;
17005		
17006		var directionX = (diffLastX < 0) ? "left":"right";
17007		var directionY = (diffLastY < 0) ? "up":"down";
17008		
17009		g_temp.lastMouseX = mousePos.pageX;
17010		g_temp.lastMouseY = mousePos.pageY;
17011		
17012		var posImage = g_functions.getElementSize(g_temp.objImage);
17013		
17014		//var imageX = g_temp.startImageX + diffX;
17015		//var imageY = g_temp.startImageY + diffY;
17016				
17017		
17018		//slow down if no pan available in this point
17019		//slow down y
17020		
17021		if(g_temp.panYActive == false){
17022			
17023			diffLastY = 0;
17024			
17025		}else{		//zoom enabled
17026			
17027			if(directionY == "down" && posImage.top > 0){			
17028				
17029				diffLastY = diffLastY / 3;				
17030				
17031			}else if(directionY == "up" && posImage.bottom < g_temp.objParentSize.height){
17032				
17033				diffLastY = diffLastY / 3;				
17034				
17035			}
17036		}
17037		
17038		//slow down x (only if the pan enabled)
17039		if(g_temp.panXActive == false || g_parent.isInnerInPlace() == false){
17040			
17041			diffLastX = 0;
17042		
17043		}else{	//zoom enabled
17044			
17045			if(directionX == "right" && posImage.left > 0){				
17046				diffLastX = diffLastX / 3;				
17047			}
17048			else if(directionX == "left" && posImage.right < g_temp.objParentSize.width){
17049				diffLastX = diffLastX / 3;
17050			}
17051	    }
17052		
17053		var imageX = posImage.left + diffLastX;
17054		var imageY = posImage.top + diffLastY;
17055		
17056		
17057		g_functions.placeElement(g_temp.objImage, imageX, imageY);
17058		
17059	}
17060	
17061	
17062	
17063	
17064	/**
17065	 * return the image to place if it's out of borders
17066	 */
17067	function checkReturnAfterPan(){
17068				
17069		var isReturnX = false, isReturnY = false, newX = 0, newY = 0;
17070		var objSize = g_functions.getElementSize(g_temp.objImage);
17071		var objImagePadding = g_parent.getObjImagePadding();
17072				
17073		var objCenterPos = g_functions.getElementCenterPosition(g_temp.objImage, objImagePadding);
17074		
17075		g_temp.panXActive = (g_temp.objImageSize.width > g_temp.objParentSize.width);
17076		g_temp.panYActive = (g_temp.objImageSize.height > g_temp.objParentSize.height);
17077				
17078		
17079		if(g_temp.panYActive == true){
17080			
17081			if(objSize.top > 0){		//off limit top
17082				
17083				newY = 0;
17084				isReturnY = true;
17085				
17086			}else if(objSize.bottom < g_temp.objParentSize.height){		//off limit bottom
17087				
17088				newY = g_temp.objParentSize.height - objSize.height;
17089				isReturnY = true;
17090				
17091			}
17092			
17093		}else{		//pan not active y - return to center
17094			
17095			if(objSize.top != objCenterPos.top){
17096				isReturnY = true;
17097				newY = objCenterPos.top;
17098			}
17099			
17100		}
17101		
17102		
17103		//check return x to place
17104		if(g_temp.panXActive == true){
17105			
17106			if(objSize.left > 0){		//off limit left
17107				
17108				newX = 0;
17109				isReturnX = true;
17110				
17111			}else if(objSize.right < g_temp.objParentSize.width){		//off limit right
17112								
17113				newX = g_temp.objParentSize.width - objSize.width;
17114				isReturnX = true;
17115				
17116			}
17117			
17118		}else{		//pan not active x - return to center
17119			
17120		//	debugLine("not active", true);
17121			
17122			if(objSize.left != objCenterPos.left){
17123				isReturnX = true;
17124				newX = objCenterPos.left;
17125			}
17126		}
17127		
17128		
17129		//do the animation
17130		var objCss = {};
17131		if(isReturnY == true)
17132			objCss.top = newY + "px";
17133		
17134		if(isReturnX == true)
17135			objCss.left = newX + "px";
17136		
17137		
17138		if(isReturnY == true || isReturnX == true){
17139						
17140			g_temp.objImage.animate(objCss,{
17141				duration: g_options.slider_zoom_return_pan_duration,
17142				easing: g_options.slider_zoom_return_pan_easing,
17143				queue: false
17144			});
17145
17146		}
17147		
17148	}
17149	
17150	/**
17151	 * check if the image animating or not
17152	 */
17153	function isImageAnimating(){
17154		
17155		if(g_temp.objImage && g_temp.objImage.is(":animated"))
17156			return(true);
17157		
17158		return(false);
17159	}
17160	
17161	function ____________END_PAN_____________(){};
17162	
17163	function ________TOUCH_ZOOM_____________(){};
17164	
17165	/**
17166	 * start touch zoom
17167	 */
17168	function startTouchZoom(arrTouches){
17169				
17170		g_temp.isZoomActive = true;
17171		
17172		//store init diff
17173		g_temp.startDistance = g_functions.getDistance(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY);
17174		if(g_temp.startDistance == 0)
17175			g_temp.startDistance = 1;
17176		
17177		
17178		//store init positions
17179		g_temp.startMiddlePoint = g_functions.getMiddlePoint(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY);
17180				
17181		g_temp.objImageSize = g_functions.getElementSize(g_temp.objImage);
17182			
17183		g_temp.startImageX = g_temp.objImageSize.left;
17184		g_temp.startImageY = g_temp.objImageSize.top;
17185		
17186		//set orient point
17187		g_temp.imageOrientPoint = g_functions.getElementLocalPoint(g_temp.startMiddlePoint, g_temp.objImage);
17188		
17189		var isInsideImage = g_functions.isPointInsideElement(g_temp.imageOrientPoint, g_temp.objImageSize);
17190		if(isInsideImage == false){
17191			g_temp.imageOrientPoint = g_functions.getElementCenterPoint(g_temp.objImage);
17192		}
17193		
17194		//trigger start zoom event
17195		g_objParent.trigger(g_parent.events.ZOOM_START);
17196	}
17197	
17198	
17199	/**
17200	 * check num touches, if not 2 - end zoom
17201	 */
17202	function checkTouchZoomEnd(event){
17203				
17204		if(g_temp.isZoomActive == false)
17205			return(false);
17206		
17207		var arrTouches = g_functions.getArrTouches(event);			
17208		if(arrTouches.length != 2){		//end touch zoom
17209			
17210			g_temp.isZoomActive = false;
17211			
17212			//trigger end zoom event
17213			g_objParent.trigger(g_parent.events.ZOOM_END);			
17214		}	
17215		
17216	}
17217	
17218	
17219	/**
17220	 * check start touch zoom
17221	 */
17222	function checkTouchZoomStart(event){
17223				
17224		if(g_temp.isZoomActive == true)
17225			return(true);
17226
17227
17228		var arrTouches = g_functions.getArrTouches(event);
17229				
17230		if(arrTouches.length != 2)
17231			return(true);
17232					
17233		startTouchZoom(arrTouches);		
17234	}
17235	
17236	
17237	/**
17238	 * do touch zoom on touch devices
17239	 */
17240	function doTouchZoom(event){
17241				
17242		var arrTouches = g_functions.getArrTouches(event);
17243				
17244		var distance = g_functions.getDistance(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY);		
17245		var zoomRatio = distance / g_temp.startDistance;
17246		
17247		var middlePoint = g_functions.getMiddlePoint(arrTouches[0].pageX, arrTouches[0].pageY, arrTouches[1].pageX, arrTouches[1].pageY);
17248		
17249		//set zoom data:
17250		var newWidth = g_temp.objImageSize.width * zoomRatio;
17251		var newHeight = g_temp.objImageSize.height * zoomRatio;
17252		
17253		//check max zoom ratio:
17254		var objOriginalSize = g_functions.getImageOriginalSize(g_temp.objImage);
17255		var expectedZoomRatio = 1;		
17256		if(objOriginalSize.width > 0)
17257			expectedZoomRatio = newWidth / objOriginalSize.width;
17258		
17259		if(expectedZoomRatio > g_options.slider_zoom_max_ratio)
17260			return(true);
17261		
17262		//set pan data:
17263		panX = -(g_temp.imageOrientPoint.x * zoomRatio - g_temp.imageOrientPoint.x);
17264		panY = -(g_temp.imageOrientPoint.y * zoomRatio - g_temp.imageOrientPoint.y);
17265		
17266		var diffMiddleX = (middlePoint.x - g_temp.startMiddlePoint.x);
17267	    var diffMiddleY = (middlePoint.y - g_temp.startMiddlePoint.y);
17268		
17269	    var posx = g_temp.startImageX + panX + diffMiddleX;
17270		var posy = g_temp.startImageY + panY + diffMiddleY;		
17271				
17272		
17273		//resize and place:
17274		g_functions.setElementSizeAndPosition(g_temp.objImage, posx, posy, newWidth, newHeight);
17275		
17276		//trigger zooming event
17277		g_objParent.trigger(g_parent.events.ZOOMING);			
17278		g_objParent.trigger(g_parent.events.ZOOM_CHANGE);			
17279
17280		/*
17281		debugLine({
17282			middleStartX: g_temp.startMiddlePoint.x,
17283			middleX: middlePoint.x,
17284			diffMiddleX: diffMiddleX
17285		});
17286		*/
17287		
17288	}
17289	
17290	
17291	/**
17292	 * check return the image from zoom
17293	 */
17294	function checkReturnFromZoom(){
17295				
17296		if(g_temp.objImage == undefined || g_temp.objImage.length == 0)
17297			return(true);
17298		
17299		var objSize = g_functions.getElementSize(g_temp.objImage);
17300		
17301		if(objSize.width < g_temp.objFitImageSize.imageWidth){
17302			
17303			g_temp.objImage.css({
17304				position:"absolute",
17305				margin:"none"
17306			});
17307			
17308			var objCss = {
17309				top: g_temp.objFitImageSize.imageTop + "px",
17310				left: g_temp.objFitImageSize.imageLeft + "px",
17311				width: g_temp.objFitImageSize.imageWidth + "px",
17312				height: g_temp.objFitImageSize.imageHeight + "px"
17313			};
17314			
17315			g_temp.objImage.animate(objCss,{
17316				duration: g_options.slider_zoom_return_pan_duration,
17317				easing: g_options.slider_zoom_return_pan_easing,
17318				queue: false
17319			});
17320			
17321		}else{			
17322			checkReturnAfterPan();
17323		}
17324		
17325	}
17326	
17327	
17328	function ________END_TOUCH_ZOOM_____________(){};
17329	
17330	
17331	/**
17332	 * 
17333	 * touch start event - start pan, remember start pan data
17334	 */
17335	function onTouchStart(event){
17336		
17337		//if no image type, exit
17338		if(g_parent.isCurrentSlideType("image") == false)
17339			return(true);
17340		
17341		var isStored = storeCurrentImage();
17342		
17343		if(g_temp.objImage == undefined || g_temp.objImage.length == 0)
17344			return(true);
17345		
17346		event.preventDefault();
17347						
17348		//stop animation if exists
17349		if(isImageAnimating() == true){			
17350			g_temp.objImage.stop(true);
17351		}
17352		
17353		if(g_temp.isZoomActive == true){
17354			
17355			checkTouchZoomEnd(event);
17356			
17357		}else{
17358			
17359			checkTouchZoomStart(event);
17360			
17361		}
17362		
17363		//if zoom started stop panning, if not, start panning
17364		if(g_temp.isZoomActive == true){
17365			
17366			g_temp.isPanActive = false;
17367		
17368		}else if(isPanPosible(g_temp.objImage, event) == true && g_temp.isZoomedOnce == true){
17369			
17370			startPan(event);
17371		}
17372		
17373		/*
17374		debugLine({
17375				pan: g_temp.isPanActive,
17376				zoom: g_temp.isZoomActive,
17377				event: "start"
17378			}, true);
17379		*/
17380		
17381	}
17382	
17383	
17384	/**
17385	 * touch end event - bring the image to place
17386	 */
17387	function onTouchEnd(event){
17388		
17389		if(g_parent.isCurrentSlideType("image") == false)
17390			return(true);
17391		
17392		//check if some gallery button clicked
17393		var objTarget = jQuery(event.target);
17394		if(objTarget.data("ug-button") == true){
17395			//event.preventDefault();
17396			return(false);
17397		}
17398		
17399		var isStored = storeCurrentImage();
17400
17401		if(g_temp.objImage == undefined || g_temp.objImage.length == 0)
17402			return(true);
17403				
17404		var panWasActive = g_temp.isPanActive;
17405		var zoomWasActive = g_temp.isZoomActive;
17406		
17407		//if the inner not in place, don't return noting, let the slide change
17408		if(g_parent.isInnerInPlace() == false){
17409			g_temp.isZoomActive = false;
17410			g_temp.isPanActive = false;
17411			return(true);
17412		}
17413		
17414		//check end zoom
17415		if(g_temp.isZoomActive == true){
17416			checkTouchZoomEnd(event);
17417		}else{
17418			checkTouchZoomStart(event);
17419		}
17420		
17421		
17422		if(g_temp.isZoomActive == true){
17423			
17424			g_temp.isPanActive = false;
17425			
17426		}else{
17427			
17428			var panPosible = isPanPosible(g_temp.objImage, event, true);
17429			
17430			if(g_temp.isPanActive == true ){
17431						
17432				g_temp.isPanActive = false;
17433				
17434			}else if(panPosible == true){
17435				
17436				startPan(event);
17437			}
17438			
17439		}
17440		
17441		/*
17442		debugLine({
17443			pan:g_temp.isPanActive,
17444			zoom: g_temp.isZoomActive
17445		}, true);
17446		*/
17447		
17448		if((panWasActive || zoomWasActive) && g_temp.isZoomActive == false && g_temp.isPanActive == false){
17449			checkReturnFromZoom();
17450		}
17451		
17452		
17453	}
17454	
17455	
17456	/**
17457	 * 
17458	 * touch move event - pan
17459	 */
17460	function onTouchMove(event){
17461		
17462		if(g_parent.isCurrentSlideType("image") == false)
17463			return(true);
17464				
17465		//check touch zoom (pinch gesture)
17466		if(g_temp.isZoomActive == true){
17467			
17468			doTouchZoom(event);
17469			
17470		}else if(g_temp.isPanActive == true){
17471			
17472			panImage(event);
17473			
17474		}
17475		
17476		
17477	}
17478	
17479	
17480	/**
17481	 * on slider mousewheel event
17482	 */
17483	function onSliderMouseWheel(event, delta, deltaX, deltaY){
17484		
17485		if(g_options.slider_zoom_mousewheel == false)
17486			return(true);
17487		
17488		if(g_parent.isCurrentSlideType("image") == false)
17489			return(true);
17490		
17491		event.preventDefault();
17492		
17493		//prevent default only if needed
17494		//if(zoomIn == true || zoomIn == false && g_functions.isElementBiggerThenParent(objImage))
17495		//event.preventDefault();
17496		
17497		
17498		var zoomIn = (delta > 0);
17499		var mousePos = g_functions.getMousePosition(event);
17500		var	mode = (zoomIn == true) ? "in":"out";
17501		
17502		zoomCurrentImage(mode, mousePos);
17503	}
17504	
17505	
17506	/**
17507	 * init touch events
17508	 */
17509	function initEvents(){
17510		
17511		//debugLine("init");
17512		g_objSlider.on("mousewheel",onSliderMouseWheel);
17513		
17514		//slider mouse down - pan start
17515		g_objSlider.bind("mousedown touchstart",onTouchStart);
17516		
17517		//on body move
17518		jQuery("body").bind("mousemove touchmove",onTouchMove);
17519		
17520		//on body mouse up - pan end
17521		jQuery(window).add("body").bind("mouseup touchend", onTouchEnd);
17522		
17523		//event before image returned to init position
17524		g_objParent.bind(g_parent.events.BEFORE_RETURN, function(){
17525			
17526			checkReturnFromZoom();
17527		});
17528				
17529		//on item change update isZoomedOnce event. Allow panning only if zoomed once
17530		g_objParent.bind(g_parent.events.ITEM_CHANGED, function(){
17531			g_temp.isZoomedOnce = false;
17532		});
17533		
17534		g_objParent.bind(g_parent.events.ZOOM_CHANGE, function(){
17535			g_temp.isZoomedOnce = true;
17536		});
17537		
17538	}
17539	
17540	this.________EXTERNAL_____________ = function(){};
17541	
17542	/**
17543	 * check if the image is zoomed, and there is a place for left panning
17544	 */
17545	this.isPanEnabled = function(event, direction){
17546		
17547		storeCurrentImage();
17548		
17549		if(g_temp.objImage == undefined || g_temp.objImage.length == 0)
17550			return(false);
17551		
17552		if(g_temp.isZoomedOnce == false)
17553			return(false);
17554		
17555		if(isPanPosible(g_temp.objImage, event) == false)
17556			return(false);
17557		
17558		if(g_parent.isInnerInPlace() == false)
17559			return(false);
17560		
17561		if(direction == "left"){
17562			
17563			if(g_temp.objImageSize.right <= g_temp.objParentSize.width)
17564				return(false);
17565			
17566		}else{	//right direction
17567			
17568			if(g_temp.objImageSize.left >= 0)
17569				return(false);
17570		}
17571		
17572		return(true);
17573	}
17574	
17575	
17576	/**
17577	 * init function for avia controls
17578	 */
17579	this.init = function(objSlider, customOptions){
17580		
17581		initObject(objSlider, customOptions);
17582	}
17583	
17584	/**
17585	 * zoom in
17586	 */
17587	this.zoomIn = function(){		
17588		zoomCurrentImage("in");	
17589	}
17590	
17591	/**
17592	 * zoom out
17593	 */
17594	this.zoomOut = function(){		
17595		zoomCurrentImage("out");		
17596	}
17597	
17598	/**
17599	 * zoom back
17600	 */
17601	this.zoomBack = function(){
17602		
17603		zoomCurrentImage("back");		
17604	}
17605}
17606/** -------------- Wistia API ---------------------*/
17607
17608function UGWistiaAPI(){
17609	
17610	this.isAPILoaded = false;
17611	var t = this, g_objThis = jQuery(this), g_intHandle;
17612	var g_player, g_isPlayerReady = false;
17613	
17614	this.events = {
17615			START_PLAYING: "start_playing",
17616			STOP_PLAYING: "stop_playing",
17617			VIDEO_ENDED: "video_ended"
17618	};
17619
17620	
17621	/**
17622	 * check if sound cloud active
17623	 */
17624	function isWistiaActive(){
17625		
17626		return(typeof Wistia != "undefined");	
17627	}
17628	
17629	/**
17630	 * load vimeo API
17631	 */
17632	this.loadAPI = function(){
17633		
17634		if(g_ugWistiaAPI.isAPILoaded == true)
17635			return(true);
17636
17637		if(isWistiaActive()){
17638			g_ugWistiaAPI.isAPILoaded = true;
17639			return(true);
17640		}
17641		
17642		g_ugFunctions.loadJs("fast.wistia.com/assets/external/E-v1.js", true);
17643		
17644		g_ugWistiaAPI.isAPILoaded = true;		
17645	}
17646
17647	
17648	/**
17649	 * actually put the video
17650	 */
17651	function putVideoActually(divID, videoID, width, height, isAutoplay){
17652		
17653		g_player = null;
17654		g_isPlayerReady = false;
17655		
17656		var htmlID = divID + "_video";
17657		
17658		var html = "<div id='"+htmlID+"' class='wistia_embed' style='width:"+width+";height:"+height+";' data-video-width='"+width+"' data-video-height='"+height+"'>&nbsp;</div>";
17659				
17660		jQuery("#"+divID).html(html);
17661		
17662		g_player = Wistia.embed(videoID, {
17663			  version: "v1",
17664			  videoWidth: width,
17665			  videoHeight: height,
17666			  container: htmlID,
17667			  autoPlay: isAutoplay
17668		});
17669				
17670		g_isPlayerReady = true;
17671				
17672		initEvents();
17673	}
17674	
17675	
17676	/**
17677	 * init events
17678	 */
17679	function initEvents(){
17680		
17681		//set "play" event
17682		
17683		g_player.bind('play', function(){
17684			g_objThis.trigger(t.events.START_PLAYING);
17685		});
17686		
17687		//set "pause event"
17688		g_player.bind('pause', function(){
17689			g_objThis.trigger(t.events.STOP_PLAYING);
17690		});
17691		
17692		g_player.bind('end', function(){
17693			g_objThis.trigger(t.events.STOP_PLAYING);
17694			g_objThis.trigger(t.events.VIDEO_ENDED);
17695		});
17696		
17697	}
17698	
17699	
17700	/**
17701	 * do some command
17702	 */
17703	this.doCommand = function(command){
17704		
17705		if(g_player == null)
17706			return(false);
17707		
17708		if(g_isPlayerReady == false)
17709			return(false);
17710		
17711		switch(command){
17712			case "play":
17713				g_player.play();
17714			break;
17715			case "pause":
17716				g_player.pause();
17717			break;		
17718		}
17719		
17720	}
17721	
17722	/**
17723	 * do pause command
17724	 */
17725	this.pause = function(){
17726		t.doCommand("pause");
17727	}
17728	
17729	/**
17730	 * do play command
17731	 */
17732	this.play = function(){
17733		t.doCommand("play");
17734	}
17735	
17736	
17737	/**
17738	 * put the vimeo video
17739	 */
17740	this.putVideo = function(divID, videoID, width, height, isAutoplay){
17741		
17742		if(isWistiaActive()){
17743			putVideoActually(divID, videoID, width, height, isAutoplay);
17744			return(true);
17745		}
17746		
17747		
17748		//if no API present, wait for the API being ready
17749		this.loadAPI();
17750		g_intHandle = setInterval(function(){
17751			
17752			if(isWistiaActive()){
17753				putVideoActually(divID, videoID, width, height, isAutoplay);
17754				clearInterval(g_intHandle);
17755			}
17756			
17757		}, 500);
17758		
17759	}
17760	
17761	
17762	/**
17763	 * get if the player is ready
17764	 */
17765	this.isPlayerReady = function(){
17766				
17767		if(g_isPlayerReady && g_player)
17768			return(true);
17769	
17770		return(false);
17771	}	
17772	
17773	
17774}
17775
17776/** -------------- Sound Cloud API ---------------------*/
17777
17778function UGSoundCloudAPI(){
17779	
17780	this.isAPILoaded = false;
17781	var t = this, g_objThis = jQuery(this), g_intHandle;
17782	var g_player, g_lastContainerID;
17783	
17784	this.events = {
17785			START_PLAYING: "start_playing",
17786			STOP_PLAYING: "stop_playing",
17787			VIDEO_ENDED: "video_ended"
17788	};
17789
17790	/**
17791	 * check if sound cloud active
17792	 */
17793	function isSCActive(){
17794		
17795		return(typeof SC != "undefined");	
17796	}
17797	
17798	/**
17799	 * load vimeo API
17800	 */
17801	this.loadAPI = function(){
17802		
17803		if(g_ugSoundCloudAPI.isAPILoaded == true)
17804			return(true);
17805				
17806		if(isSCActive()){
17807			g_ugSoundCloudAPI.isAPILoaded = true;
17808			return(true);
17809		}
17810		
17811		g_ugFunctions.loadJs("w.soundcloud.com/player/api.js", true);
17812		
17813		g_ugSoundCloudAPI.isAPILoaded = true;		
17814	}
17815	
17816	/**
17817	 * actually put the video
17818	 */
17819	function putSoundActually(divID, trackID, width, height, isAutoplay){
17820		
17821		g_player = null;
17822		g_isPlayerReady = false;
17823		
17824		var iframeID = divID+"_iframe";
17825		
17826		var url = location.protocol+"//w.soundcloud.com/player/?url=http://api.soundcloud.com/tracks/"+trackID;
17827		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";
17828		
17829		if(isAutoplay === true)
17830			url += "&amp;auto_play=true";
17831		else
17832			url += "&amp;auto_play=false";
17833		
17834		var html = "<iframe id='"+iframeID+"' src="+url+" width='"+width+"' height='"+height+"' frameborder='0' scrolling='no' webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>";
17835		
17836		jQuery("#"+divID).html(html);
17837		
17838		//get the player object
17839		g_player = SC.Widget(iframeID);
17840		
17841		g_player.bind(SC.Widget.Events.READY, function() {
17842			
17843			if(g_player){
17844				g_isPlayerReady = true;
17845				initEvents();
17846			}
17847			
17848		});
17849		
17850		g_lastContainerID = divID;
17851	}
17852
17853	
17854	/**
17855	 * init events
17856	 */
17857	function initEvents(){
17858		
17859		
17860		//set "play" event
17861		g_player.bind(SC.Widget.Events.PLAY, function(){
17862			g_objThis.trigger(t.events.START_PLAYING);
17863		});
17864		
17865		//set "pause event"
17866		g_player.bind(SC.Widget.Events.PAUSE, function(){
17867			g_objThis.trigger(t.events.STOP_PLAYING);
17868		});
17869		
17870		g_player.bind(SC.Widget.Events.FINISH, function(){
17871			g_objThis.trigger(t.events.STOP_PLAYING);
17872			g_objThis.trigger(t.events.VIDEO_ENDED);
17873		});
17874		
17875	}
17876		
17877	
17878	/**
17879	 * put the youtube video
17880	 */
17881	this.putSound = function(divID, trackID, width, height, isAutoplay){
17882		
17883		if(isSCActive()){
17884			putSoundActually(divID, trackID, width, height, isAutoplay);
17885			return(true);
17886		}
17887		
17888		
17889		//if no API present, wait for the API being ready
17890		this.loadAPI();
17891		g_intHandle = setInterval(function(){
17892			
17893			if(isSCActive()){
17894				putSoundActually(divID, trackID, width, height, isAutoplay);
17895				clearInterval(g_intHandle);
17896			}
17897			
17898		}, 500);
17899		
17900	}
17901	
17902
17903	/**
17904	 * do some command
17905	 */
17906	this.doCommand = function(command){
17907		
17908		if(g_player == null)
17909			return(false);
17910		
17911		if(g_isPlayerReady == false)
17912			return(false);
17913		
17914		switch(command){
17915			case "play":
17916				g_player.play();
17917			break;
17918			case "pause":
17919				g_player.pause();
17920			break;
17921		}
17922		
17923	}	
17924	
17925	
17926	/**
17927	 * pause video
17928	 */
17929	this.pause = function(){
17930		t.doCommand("pause");
17931	}
17932	
17933	
17934	/**
17935	 * play video
17936	 */
17937	this.play = function(){
17938		t.doCommand("play");
17939	}
17940	
17941	/**
17942	 * destroy the player
17943	 */
17944	this.destroy = function(){
17945		
17946		g_isPlayerReady = false;
17947		g_player = null;
17948		
17949		if(g_lastContainerID){
17950			jQuery("#" + g_lastContainerID).html("");
17951			g_lastContainerID = null;
17952		}
17953		
17954	}
17955	
17956}
17957
17958/** -------------- html5 Video API ---------------------*/
17959
17960function UGHtml5MediaAPI(){
17961	
17962	this.isAPILoaded = false;
17963	var t = this, g_objThis = jQuery(this), g_intHandle;
17964	var g_player;
17965	
17966	this.events = {
17967			START_PLAYING: "start_playing",
17968			STOP_PLAYING: "stop_playing",
17969			VIDEO_ENDED: "video_ended"
17970	};
17971	
17972	/**
17973	 * load vimeo API
17974	 */
17975	this.loadAPI = function(){
17976		
17977		if(g_ugHtml5MediaAPI.isAPILoaded == true)
17978			return(true);
17979		
17980		
17981		if(isMediaElementActive()){
17982			g_ugHtml5MediaAPI.isAPILoaded = true;
17983			return(true);
17984		}
17985		
17986		g_ugFunctions.loadJs("cdnjs.cloudflare.com/ajax/libs/mediaelement/2.18.1/mediaelement.min.js", true);
17987		g_ugFunctions.loadCss("cdnjs.cloudflare.com/ajax/libs/mediaelement/2.18.1/mediaelementplayer.min.css", true);
17988		
17989		g_ugHtml5MediaAPI.isAPILoaded = true;		
17990	}
17991	
17992	/**
17993	 * return true if the mediaelement is active
17994	 */
17995	function isMediaElementActive(){
17996				
17997		return(typeof mejs != "undefined");
17998	}
17999	
18000	
18001	/**
18002	 * actually put the video
18003	 */
18004	function putVideoActually(divID, data, width, height, isAutoplay){
18005		
18006		g_player = null;
18007		g_isPlayerReady = false;
18008		
18009		var urlFlash = location.protocol + "//cdnjs.cloudflare.com/ajax/libs/mediaelement/2.18.1/flashmediaelement-cdn.swf";
18010		var urlSilverlight = location.protocol + "//cdnjs.cloudflare.com/ajax/libs/mediaelement/2.18.1/silverlightmediaelement.xap";
18011
18012		var htmlID = divID + "_video";
18013		var htmlAutoplay = "";
18014		if(isAutoplay && isAutoplay === true)
18015			htmlAutoplay = "autoplay='autoplay'"
18016		
18017		var htmlPoster = "";
18018		if(data.posterImage)
18019			htmlPoster = "poster='"+data.posterImage+"'";
18020		
18021		var html = "<video id='"+htmlID+"' width='"+width+"' height='"+height+"'  controls='controls' preload='none' "+htmlAutoplay+" "+htmlPoster+">";
18022				
18023		if(data.mp4 != "")
18024			html += "<source type='video/mp4' src='"+data.mp4+"' />";
18025		
18026		if(data.webm != "")
18027			html += "<source type='video/webm' src='"+data.webm+"' />";
18028
18029		if(data.ogv != "")
18030			html += "<source type='video/ogg' src='"+data.ogv+"' />";
18031		 
18032		html +=  "<object width='"+width+"' height='"+height+"' type='application/x-shockwave-flash' data='"+urlFlash+"'>";
18033		html +=  "<param name='movie' value='"+urlFlash+"' />";
18034		html +=  "<param name='flashvars' value='controls=true&file="+data.mp4+"' />";
18035		html +=  "</object>";
18036		
18037		html += "</video>";
18038		
18039		jQuery("#"+divID).html(html);
18040		
18041		new MediaElement(htmlID, {			
18042		    enablePluginDebug: false,
18043		    flashName: urlFlash,
18044		    silverlightName: urlSilverlight,
18045		    success: function (mediaElement, domObject) { 
18046		    	g_isPlayerReady = true;
18047		    	g_player = mediaElement;
18048		    			    	
18049		    	if(isAutoplay == false)
18050		    		g_player.pause();
18051		    	
18052		    	initEvents();
18053		    },
18054		    error: function (objError) { 
18055		    	trace(objError);
18056		    }
18057		});		
18058		
18059	}
18060	
18061	
18062	/**
18063	 * init player events function
18064	 */
18065	function initEvents(){
18066		
18067		g_ugFunctions.addEvent(g_player, "play", function(){
18068			g_objThis.trigger(t.events.START_PLAYING);
18069		});
18070		
18071		g_ugFunctions.addEvent(g_player, "pause", function(){
18072			g_objThis.trigger(t.events.STOP_PLAYING);
18073		});
18074		
18075		g_ugFunctions.addEvent(g_player, "ended", function(){
18076			g_objThis.trigger(t.events.STOP_PLAYING);
18077			g_objThis.trigger(t.events.VIDEO_ENDED);
18078		});
18079		
18080	}
18081	
18082	
18083	/**
18084	 * put the vimeo video
18085	 */
18086	this.putVideo = function(divID, data, width, height, isAutoplay){
18087		
18088		if(isMediaElementActive()){
18089			putVideoActually(divID, data, width, height, isAutoplay);
18090			return(true);
18091		}
18092		
18093		
18094		//if no API present, wait for the API being ready
18095		this.loadAPI();
18096		g_intHandle = setInterval(function(){
18097			
18098			if(isMediaElementActive()){
18099				putVideoActually(divID, data, width, height, isAutoplay);
18100				clearInterval(g_intHandle);
18101			}
18102			
18103		}, 500);
18104		
18105	}
18106
18107	/**
18108	 * do some command
18109	 */
18110	this.doCommand = function(command){
18111				
18112		if(g_player == null)
18113			return(false);
18114		
18115		if(g_isPlayerReady == false)
18116			return(false);
18117		
18118		switch(command){
18119			case "play":
18120				g_player.play();
18121			break;
18122			case "pause":
18123				g_player.pause();
18124			break;
18125		}
18126		
18127	}	
18128	
18129	
18130	/**
18131	 * pause video
18132	 */
18133	this.pause = function(){
18134		t.doCommand("pause");
18135	}
18136	
18137	
18138	/**
18139	 * play video
18140	 */
18141	this.play = function(){
18142		t.doCommand("play");
18143	}
18144	
18145}
18146
18147
18148/** -------------- Vimeo API class ---------------------*/
18149
18150function UGVimeoAPI(){
18151	
18152	this.isAPILoaded = false;
18153	
18154	var t = this, g_objThis = jQuery(this), g_intHandle;
18155	var g_player = null, g_isPlayerReady = false, g_lastCotnainerID, g_cueChangeAutoplay = false;
18156	
18157	
18158	this.events = {
18159			START_PLAYING: "start_playing",
18160			STOP_PLAYING: "stop_playing",
18161			VIDEO_ENDED: "video_ended"
18162	};
18163	
18164	/**
18165	 * load vimeo API
18166	 */
18167	this.loadAPI = function(){
18168		
18169		if(g_ugVimeoAPI.isAPILoaded == true)
18170			return(true);
18171		
18172		if(isFroogaloopActive()){
18173			g_ugVimeoAPI.isAPILoaded = true;
18174			return(true);
18175		}
18176
18177		g_ugFunctions.loadJs("f.vimeocdn.com/js/froogaloop2.min.js", true);
18178		
18179		g_ugVimeoAPI.isAPILoaded = true;		
18180	}
18181	
18182	
18183	
18184	/**
18185	 * tells if the froogaloop library active
18186	 */
18187	function isFroogaloopActive(){
18188		
18189		return(typeof Froogaloop != "undefined");
18190	}
18191	
18192	
18193	/**
18194	 * actually put the video
18195	 */
18196	function putVideoActually(divID, videoID, width, height, isAutoplay){
18197		
18198		g_player = null;
18199		g_isPlayerReady = false;
18200		
18201		var url = location.protocol+"//player.vimeo.com/video/"+videoID+"?api=1";
18202		
18203		if(isAutoplay === true)
18204		   url += "&amp;byline=0&amp;autoplay=1&amp;title=0&amp;portrait=0";
18205		
18206		var html = "<iframe src="+url+" width='"+width+"' height='"+height+"' frameborder='0' webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>";
18207		
18208		jQuery("#"+divID).html(html);
18209		
18210		//get the player object
18211		var iframe = jQuery("#"+divID + " iframe")[0];
18212		
18213		g_player = Froogaloop(iframe);
18214
18215		g_player.addEvent('ready', function(){
18216			
18217			if(g_player){
18218				g_isPlayerReady = true;
18219				initEvents();
18220			}
18221			
18222		});
18223		
18224		g_lastCotnainerID = divID;		
18225	}
18226	
18227	/**
18228	 * init events
18229	 */
18230	function initEvents(){
18231		
18232		if(!g_player)
18233			return(false);
18234				
18235		//set "cuechange" event
18236		g_player.addEvent('cuechange', function(){
18237			
18238			if(g_cueChangeAutoplay == true)			
18239				t.play();
18240			
18241		});
18242		
18243		//set "play" event
18244		g_player.addEvent('play', function(){
18245			g_objThis.trigger(t.events.START_PLAYING);
18246		});
18247		
18248		//set "pause event"
18249		g_player.addEvent('pause', function(){
18250			g_objThis.trigger(t.events.STOP_PLAYING);
18251		});
18252		
18253		g_player.addEvent('finish', function(){
18254			g_objThis.trigger(t.events.STOP_PLAYING);
18255			g_objThis.trigger(t.events.VIDEO_ENDED);
18256		});
18257		
18258	}
18259	
18260	
18261	/**
18262	 * do some command
18263	 */
18264	this.doCommand = function(command){
18265		
18266		if(g_player == null)
18267			return(false);
18268		
18269		if(g_isPlayerReady == false)
18270			return(false);
18271		
18272		switch(command){
18273			default:
18274				g_player.api(command);
18275			break;
18276		}
18277		
18278	}
18279	
18280	/**
18281	 * do pause command
18282	 */
18283	this.pause = function(){
18284		t.doCommand("pause");
18285	}
18286	
18287	/**
18288	 * do play command
18289	 */
18290	this.play = function(){
18291		t.doCommand("play");
18292	}
18293	
18294	/**
18295	 * desrtoy the player and empty the div
18296	 */
18297	this.destroy = function(){
18298		
18299		if(g_player){
18300			g_player.api("unload");
18301			g_player = null;
18302			g_isPlayerReady = false;
18303		}
18304		
18305		if(g_lastCotnainerID){
18306			jQuery("#" + g_lastCotnainerID).html("");			
18307		}
18308	
18309	}
18310	
18311	/**
18312	 * put the vimeo video
18313	 */
18314	this.putVideo = function(divID, videoID, width, height, isAutoplay){
18315		
18316		if(isFroogaloopActive()){
18317			putVideoActually(divID, videoID, width, height, isAutoplay);
18318			return(true);
18319		}
18320		
18321		
18322		//if no API present, wait for the API being ready
18323		this.loadAPI();
18324		g_intHandle = setInterval(function(){
18325			
18326			if(isFroogaloopActive()){
18327				putVideoActually(divID, videoID, width, height, isAutoplay);
18328				clearInterval(g_intHandle);
18329			}
18330			
18331		}, 500);
18332		
18333	}
18334	
18335	
18336	/**
18337	 * get if the player is ready
18338	 */
18339	this.isPlayerReady = function(){
18340		
18341		if(g_isPlayerReady && g_player)
18342			return(true);
18343	
18344		return(false);
18345	}	
18346	
18347	/**
18348	 * change the video
18349	 */
18350	this.changeVideo = function(videoID, isAutoplay){
18351		
18352		if(t.isPlayerReady() == false)
18353			return(false);
18354		
18355		g_cueChangeAutoplay = isAutoplay;
18356		
18357		g_player.api("loadVideo", videoID);
18358	}
18359	
18360	
18361	/**
18362	 * get video images
18363	 */
18364	this.getVideoImages = function(videoID, itemIndex, onSuccessFunction){
18365		
18366		var url = location.protocol+"//vimeo.com/api/v2/video/"+videoID+".json";
18367		jQuery.get(url, {}, function(data){
18368			var obj = {};
18369			obj.preview = data[0].thumbnail_large;
18370			obj.thumb = data[0].thumbnail_medium;
18371			onSuccessFunction(itemIndex, obj);
18372		});
18373	}
18374	
18375	
18376}
18377
18378
18379/** -------------- Youtube API class ---------------------*/
18380
18381function UGYoutubeAPI(){
18382	
18383	this.isAPILoaded = false;	
18384	var t = this, g_player = null, g_intHandle, g_isPlayerReady = false;
18385	var g_objThis = jQuery(this), g_prevState = -1, g_lastContainerID;	//unstarted
18386	
18387	var g_options = {
18388			video_youtube_showinfo: true
18389	}
18390	
18391	this.events = {
18392		START_PLAYING: "start_playing",
18393		STOP_PLAYING: "stop_playing",
18394		VIDEO_ENDED: "video_ended"
18395	};
18396	
18397	
18398	/**
18399	 * actually put the video
18400	 */
18401	function putVideoActually(divID, videoID, width, height, isAutoplay){
18402				
18403		if(g_player && g_isPlayerReady){			
18404			g_player.destroy();
18405		}
18406		
18407		var playerVars = {
18408			controls:2,
18409			showinfo:g_options.video_youtube_showinfo, 
18410			rel:0
18411		};
18412		
18413		if(isAutoplay === true)
18414			playerVars.autoplay = 1;
18415			
18416		g_isPlayerReady = false;
18417
18418		g_player = new YT.Player(divID, {
18419		      height: height,
18420		      width: width,
18421		      videoId: videoID,
18422		      playerVars: playerVars,
18423		      events: {
18424		        'onReady': onPlayerReady,
18425		        'onStateChange': onPlayerStateChange
18426		      }
18427		 });
18428		
18429		g_lastContainerID = divID;
18430	}
18431	
18432	
18433	/**
18434	 * check if YT active
18435	 */
18436	function isYTActive(){
18437		
18438		if(typeof YT != "undefined" && typeof YT.Player != "undefined")
18439			return(true);
18440		
18441		return(false);
18442	}
18443	
18444	
18445	/**
18446	 * set options
18447	 */
18448	this.setOptions = function(objOptions){
18449		g_options = jQuery.extend(g_options, objOptions);
18450	}
18451	
18452	
18453	/**
18454	 * put the youtube video
18455	 */
18456	this.putVideo = function(divID, videoID, width, height, isAutoplay){
18457		
18458		if(isYTActive()){
18459			putVideoActually(divID, videoID, width, height, isAutoplay);
18460			return(true);
18461		}
18462		
18463		//if no API present, wait for the API being ready
18464		this.loadAPI();
18465		g_intHandle = setInterval(function(){
18466			
18467			if(isYTActive()){
18468				putVideoActually(divID, videoID, width, height, isAutoplay);
18469				clearInterval(g_intHandle);
18470			}
18471			
18472		}, 500);
18473		
18474	}
18475	
18476	
18477	/**
18478	 * on player ready event
18479	 */
18480	function onPlayerReady(){
18481		g_isPlayerReady = true;
18482	}
18483	
18484	
18485	/**
18486	 * on player state change event
18487	 * trigger events
18488	 */
18489	function onPlayerStateChange(){
18490		
18491		if(typeof g_player.getPlayerState != "function"){
18492			trace("Youtube API error: can't get player state");
18493			return(false);
18494		}
18495		
18496		var state = g_player.getPlayerState();
18497		
18498		switch(state){
18499			case YT.PlayerState.PLAYING:
18500				g_objThis.trigger(t.events.START_PLAYING);
18501			break;
18502			case YT.PlayerState.ENDED:
18503				g_objThis.trigger(t.events.STOP_PLAYING);					
18504				g_objThis.trigger(t.events.VIDEO_ENDED);
18505			break;
18506			default:
18507				if(g_prevState == YT.PlayerState.PLAYING)
18508					g_objThis.trigger(t.events.STOP_PLAYING);					
18509			break;
18510		}
18511		
18512		g_prevState = state;
18513	}
18514	
18515	
18516	/**
18517	 * load youtube API
18518	 */
18519	this.loadAPI = function(){
18520		
18521		if(g_ugYoutubeAPI.isAPILoaded == true)
18522			return(true);
18523		
18524		if(typeof YT != "undefined"){
18525			g_ugYoutubeAPI.isAPILoaded = true;
18526			return(true);
18527		}
18528		
18529		g_ugFunctions.loadJs("https://www.youtube.com/player_api", false);
18530		
18531		g_ugYoutubeAPI.isAPILoaded = true;	
18532		
18533	}
18534	
18535	
18536	/**
18537	 * do some command
18538	 */
18539	this.doCommand = function(command, opt1){
18540		
18541		if(!g_player)
18542			return(true);
18543		
18544		if(g_isPlayerReady == false)
18545			return(false);
18546		
18547		switch(command){
18548			case "play":
18549				if(typeof g_player.playVideo != "function")
18550					return(false);
18551				
18552				g_player.playVideo();
18553			break;
18554			case "pause":
18555				if(typeof g_player.pauseVideo != "function")
18556					return(false);
18557				
18558				g_player.pauseVideo();
18559			break;
18560			case "seek":
18561				if(typeof g_player.seekTo != "function")
18562					return(false);
18563
18564				g_player.seekTo(opt1);
18565			break;
18566			case "stopToBeginning":
18567				var state = g_player.getPlayerState();
18568				
18569				g_player.pauseVideo();
18570				
18571				switch(state){
18572					case YT.PlayerState.PLAYING:
18573					case YT.PlayerState.ENDED:
18574					case YT.PlayerState.PAUSED:
18575						g_player.seekTo(0);
18576					break;
18577				}
18578			break;
18579		}
18580	}
18581	
18582	/**
18583	 * play video
18584	 */
18585	this.play = function(){
18586		t.doCommand("play");		
18587	}
18588	
18589	/**
18590	 * stop the video
18591	 */
18592	this.pause = function(){
18593		t.doCommand("pause");
18594	}
18595	
18596	/**
18597	 * destroy player
18598	 */
18599	this.destroy = function(){
18600		try{
18601			
18602			if(g_player){
18603				g_isPlayerReady = false;	
18604				g_player.clearVideo();
18605				g_player.destroy();
18606			}
18607			
18608		}catch(objError){
18609			
18610			jQuery("#"+g_lastContainerID).html("");
18611			
18612		}
18613		
18614	}
18615	
18616	/**
18617	 * stop the video and seek to start
18618	 */
18619	this.stopToBeginning = function(){
18620		t.doCommand("stopToBeginning");
18621	}
18622	
18623	/**
18624	 * change the video
18625	 */
18626	this.changeVideo = function(videoID, isAutoplay){
18627		
18628		if(t.isPlayerReady() == false)
18629			return(false);
18630		
18631		if(isAutoplay && isAutoplay == true)
18632			g_player.loadVideoById(videoID, 0, "large");
18633		else
18634			g_player.cueVideoById(videoID, 0, "large");
18635	}
18636	
18637	
18638	/**
18639	 * get if the player is ready
18640	 */
18641	this.isPlayerReady = function(){
18642		
18643		if(g_isPlayerReady && g_player)
18644			return(true);
18645	
18646		return(false);
18647	}
18648	
18649		
18650	
18651	/**
18652	 * get preview and thumbs images according the ID
18653	 */
18654	this.getVideoImages = function(videoID){
18655		var obj = {};
18656		obj.preview = "https://i.ytimg.com/vi/"+videoID+"/sddefault.jpg";
18657		obj.thumb = "https://i.ytimg.com/vi/"+videoID+"/default.jpg";
18658		return(obj);
18659	}
18660	
18661	
18662}
18663
18664/** -------------- Video Player Class ---------------------*/
18665
18666
18667function UGVideoPlayer(){
18668	
18669	var t = this, g_galleryID, g_objThis = jQuery(this), g_functions = new UGFunctions();
18670	var g_youtubeAPI = new UGYoutubeAPI(), g_vimeoAPI = new UGVimeoAPI();
18671	var g_html5API = new UGHtml5MediaAPI(), g_soundCloudAPI = new UGSoundCloudAPI(), g_wistiaAPI = new UGWistiaAPI();
18672	var g_objPlayer, g_objYoutube, g_objVimeo, g_objHtml5, g_objButtonClose, g_objSoundCloud, g_objWistia;
18673	var g_activePlayerType = null;
18674	
18675	var g_options = {
18676			video_enable_closebutton: true
18677	};
18678	
18679	this.events = {
18680			SHOW: "video_show",
18681			HIDE: "video_hide",
18682			PLAY_START: "video_play_start",
18683			PLAY_STOP: "video_play_stop",
18684			VIDEO_ENDED: "video_ended"
18685	};
18686	
18687	var g_temp = {
18688			standAloneMode: false,
18689			youtubeInnerID:"",
18690			vimeoPlayerID:"",
18691			html5PlayerID:"",
18692			wistiaPlayerID:"",
18693			soundCloudPlayerID:""
18694	};
18695	
18696	
18697	/**
18698	 * init the object
18699	 */
18700	this.init = function(optOptions, isStandAloneMode, galleryID){
18701		g_galleryID = galleryID;
18702		
18703		if(!g_galleryID)
18704			throw new Error("missing gallery ID for video player, it's a must!");
18705			
18706		g_options =  jQuery.extend(g_options, optOptions);
18707		
18708		g_youtubeAPI.setOptions(g_options);
18709		
18710		if(isStandAloneMode && isStandAloneMode == true)
18711			g_temp.standAloneMode = true;
18712		
18713	}
18714	
18715	
18716	/**
18717	 * set the player html
18718	 */
18719	this.setHtml = function(objParent){
18720		
18721		g_temp.youtubeInnerID = g_galleryID + "_youtube_inner";
18722		g_temp.vimeoPlayerID = g_galleryID + "_videoplayer_vimeo";
18723		g_temp.html5PlayerID = g_galleryID + "_videoplayer_html5";
18724		g_temp.wistiaPlayerID = g_galleryID + "_videoplayer_wistia";
18725		g_temp.soundCloudPlayerID = g_galleryID + "_videoplayer_soundcloud";
18726		
18727		
18728		var html = "<div class='ug-videoplayer' style='display:none'>";
18729		html += "<div class='ug-videoplayer-wrapper ug-videoplayer-youtube' style='display:none'><div id='"+g_temp.youtubeInnerID+"'></div></div>";
18730		html += "<div id='"+g_temp.vimeoPlayerID+"' class='ug-videoplayer-wrapper ug-videoplayer-vimeo' style='display:none'></div>";
18731		html += "<div id='"+g_temp.html5PlayerID+"' class='ug-videoplayer-wrapper ug-videoplayer-html5'></div>";
18732		html += "<div id='"+g_temp.soundCloudPlayerID+"' class='ug-videoplayer-wrapper ug-videoplayer-soundcloud'></div>";
18733		html += "<div id='"+g_temp.wistiaPlayerID+"' class='ug-videoplayer-wrapper ug-videoplayer-wistia'></div>";
18734		
18735		if(g_temp.standAloneMode == false && g_options.video_enable_closebutton == true)
18736			html += "<div class='ug-videoplayer-button-close'></div>";
18737		
18738		html += "</div>";
18739		
18740		objParent.append(html);
18741		
18742		g_objPlayer = objParent.children(".ug-videoplayer");
18743		g_objYoutube = g_objPlayer.children(".ug-videoplayer-youtube");
18744		g_objVimeo = g_objPlayer.children(".ug-videoplayer-vimeo");
18745		g_objHtml5 = g_objPlayer.children(".ug-videoplayer-html5");
18746		g_objSoundCloud = g_objPlayer.children(".ug-videoplayer-soundcloud");
18747		g_objWistia = g_objPlayer.children(".ug-videoplayer-wistia");
18748		
18749		if(g_temp.standAloneMode == false && g_options.video_enable_closebutton == true)
18750			g_objButtonClose = g_objPlayer.children(".ug-videoplayer-button-close")
18751	}
18752
18753	
18754	function __________EVENTS___________(){};	
18755	
18756	/**
18757	 * on close button click event
18758	 */
18759	function onCloseButtonClick(){
18760		t.hide();
18761	}
18762	
18763	/**
18764	 * on some video play start
18765	 */
18766	function onPlayStart(){
18767		
18768		g_objThis.trigger(t.events.PLAY_START);
18769		
18770		if(g_objButtonClose)
18771			g_objButtonClose.hide();
18772	}
18773	
18774	
18775	/**
18776	 * on some video play stop
18777	 */
18778	function onPlayStop(){
18779		
18780		g_objThis.trigger(t.events.PLAY_STOP);
18781		
18782		if(g_objButtonClose)
18783			g_objButtonClose.show();
18784	}
18785	
18786	/**
18787	 * on video ended
18788	 */
18789	function onVideoEnded(){
18790		
18791		g_objThis.trigger(t.events.VIDEO_ENDED);
18792		
18793	}
18794
18795	
18796	/**
18797	 * init events
18798	 */
18799	function initEvents(){
18800		
18801		//close button events
18802		if(g_objButtonClose){
18803			g_functions.setButtonMobileReady(g_objButtonClose);		
18804			g_functions.setButtonOnClick(g_objButtonClose, onCloseButtonClick);					
18805		}
18806		
18807		//youtube events
18808		jQuery(g_youtubeAPI).on(g_youtubeAPI.events.START_PLAYING, onPlayStart);
18809		jQuery(g_youtubeAPI).on(g_youtubeAPI.events.STOP_PLAYING, onPlayStop);
18810		jQuery(g_youtubeAPI).on(g_youtubeAPI.events.VIDEO_ENDED, onVideoEnded);
18811		
18812		//vimeo events
18813		jQuery(g_vimeoAPI).on(g_vimeoAPI.events.START_PLAYING, onPlayStart);
18814		jQuery(g_vimeoAPI).on(g_vimeoAPI.events.STOP_PLAYING, onPlayStop);
18815		jQuery(g_vimeoAPI).on(g_vimeoAPI.events.VIDEO_ENDED, onVideoEnded);
18816		
18817		//html5 video events
18818		jQuery(g_html5API).on(g_html5API.events.START_PLAYING, onPlayStart);
18819		jQuery(g_html5API).on(g_html5API.events.STOP_PLAYING, onPlayStop);
18820		jQuery(g_html5API).on(g_html5API.events.VIDEO_ENDED, onVideoEnded);
18821		
18822		jQuery(g_soundCloudAPI).on(g_soundCloudAPI.events.START_PLAYING, onPlayStart);
18823		jQuery(g_soundCloudAPI).on(g_soundCloudAPI.events.STOP_PLAYING, onPlayStop);
18824		jQuery(g_soundCloudAPI).on(g_soundCloudAPI.events.VIDEO_ENDED, onVideoEnded);
18825		
18826		jQuery(g_wistiaAPI).on(g_wistiaAPI.events.START_PLAYING, onPlayStart);
18827		jQuery(g_wistiaAPI).on(g_wistiaAPI.events.STOP_PLAYING, onPlayStop);
18828		jQuery(g_wistiaAPI).on(g_wistiaAPI.events.VIDEO_ENDED, onVideoEnded);
18829		
18830	}
18831	
18832	
18833	/**
18834	 * destroy the video player events
18835	 */
18836	this.destroy = function(){
18837		
18838		if(g_objButtonClose){
18839			g_objButtonClose.off("click");
18840			g_objButtonClose.off("touchend");
18841		}
18842		
18843		//youtube events
18844		jQuery(g_youtubeAPI).off(g_youtubeAPI.events.START_PLAYING);
18845		jQuery(g_youtubeAPI).off(g_youtubeAPI.events.STOP_PLAYING);
18846		
18847		//vimeo events
18848		jQuery(g_vimeoAPI).off(g_vimeoAPI.events.START_PLAYING);
18849		jQuery(g_vimeoAPI).off(g_vimeoAPI.events.STOP_PLAYING);
18850		
18851		//html5 video events
18852		jQuery(g_html5API).off(g_html5API.events.START_PLAYING);
18853		jQuery(g_html5API).off(g_html5API.events.STOP_PLAYING);
18854		
18855		jQuery(g_soundCloudAPI).off(g_soundCloudAPI.events.START_PLAYING, onPlayStart);
18856		jQuery(g_soundCloudAPI).off(g_soundCloudAPI.events.STOP_PLAYING, onPlayStop);
18857		
18858		jQuery(g_wistiaAPI).off(g_wistiaAPI.events.START_PLAYING, onPlayStart);
18859		jQuery(g_wistiaAPI).off(g_wistiaAPI.events.STOP_PLAYING, onPlayStop);
18860		
18861		g_activePlayerType = null;
18862	}
18863	
18864	
18865	/**
18866	 * init events
18867	 */
18868	this.initEvents = function(){
18869		
18870		initEvents();
18871	}
18872	
18873	
18874	/**
18875	 * set element size and position the button
18876	 */
18877	this.setSize = function(width, height){
18878		
18879		g_functions.setElementSize(g_objPlayer, width, height);
18880		
18881		if(g_objButtonClose)
18882			g_functions.placeElement(g_objButtonClose, "right", "top");
18883		
18884	}
18885	
18886	
18887	/**
18888	 * set video player position
18889	 */
18890	this.setPosition = function(left, top){
18891		g_functions.placeElement(g_objPlayer, left, top);
18892	}
18893	
18894	/**
18895	 * get video player object for placing
18896	 */
18897	this.getObject = function(){
18898		return(g_objPlayer);
18899	}
18900	
18901	
18902	/**
18903	 * show the player
18904	 */
18905	this.show = function(){		
18906		
18907		if(t.isVisible() == true)
18908			return(true);
18909		
18910		g_objPlayer.show();
18911		
18912		g_objPlayer.fadeTo(0,1);
18913		
18914		if(g_objButtonClose)
18915			g_objButtonClose.show();
18916				
18917		g_objThis.trigger(t.events.SHOW);
18918	}
18919		
18920	
18921	/**
18922	 * hide the player
18923	 */
18924	this.hide = function(){
18925		
18926		if(t.isVisible() == false)
18927			return(true);
18928		
18929		//pause all players
18930		stopAndHidePlayers();
18931		
18932		g_activePlayerType = null;
18933		
18934		g_objPlayer.hide();
18935		
18936		g_objThis.trigger(t.events.HIDE);
18937	}
18938	
18939	
18940	/**
18941	 * get active player
18942	 */
18943	this.getActiveAPI = function(){
18944		
18945		switch(g_activePlayerType){
18946			case "youtube":
18947				return g_youtubeAPI;
18948			break;
18949			case "vimeo":
18950				return g_vimeoAPI;
18951			break;
18952			case "wistia":
18953				return g_wistiaAPI;
18954			break;
18955			case "soundcloud":
18956				return g_soundCloudAPI;
18957			break;
18958			case "html5":
18959				return g_html5API;
18960			break;
18961			default:
18962				return null;
18963			break;
18964		}
18965	}
18966	
18967	
18968	/**
18969	 * pause active player if playing
18970	 */
18971	this.pause = function(){
18972		
18973		var activeAPI = t.getActiveAPI();
18974		if(activeAPI == null)
18975			return(false);
18976		
18977		if(typeof activeAPI.pause == "function")
18978			activeAPI.pause();
18979			
18980	}
18981	
18982	
18983	/**
18984	 * return if the player is visible
18985	 */
18986	this.isVisible = function(){
18987		
18988		return g_objPlayer.is(":visible");
18989	}
18990	
18991	
18992	/**
18993	 * stop and hide other elements except some
18994	 */
18995	function stopAndHidePlayers(except){
18996		
18997		var arrPlayers = ["youtube", "vimeo", "html5", "soundcloud", "wistia"];
18998		for(var index in arrPlayers){
18999			var player = arrPlayers[index];
19000			if(player == except)
19001				continue;
19002			switch(player){
19003				case "youtube":		
19004					g_youtubeAPI.pause();
19005					g_youtubeAPI.destroy();	
19006					g_objYoutube.hide();
19007				break;
19008				case "vimeo":
19009					g_vimeoAPI.pause();
19010					g_vimeoAPI.destroy();
19011					g_objVimeo.hide();
19012				break;
19013				case "html5":
19014					g_html5API.pause();
19015					g_objHtml5.hide();
19016				break;
19017				case "soundcloud":
19018					g_soundCloudAPI.pause();
19019					g_soundCloudAPI.destroy();
19020					g_objSoundCloud.hide();
19021				break;
19022				case "wistia":
19023					g_wistiaAPI.pause();
19024					g_objWistia.hide();
19025				break;
19026			}
19027		}
19028		
19029	}
19030	
19031	
19032	/**
19033	 * play youtube inside the video, isAutoplay - true by default
19034	 */
19035	this.playYoutube = function(videoID, isAutoplay){
19036				
19037		if(typeof isAutoplay == "undefined")
19038			var isAutoplay = true;
19039		
19040		stopAndHidePlayers("youtube");
19041		
19042		g_objYoutube.show();
19043		
19044		var objYoutubeInner = g_objYoutube.children("#"+g_temp.youtubeInnerID);
19045		if(objYoutubeInner.length == 0)
19046			g_objYoutube.append("<div id='"+g_temp.youtubeInnerID+"'></div>");
19047			
19048		
19049		if(g_youtubeAPI.isPlayerReady() == true && g_temp.standAloneMode == true)
19050			g_youtubeAPI.changeVideo(videoID, isAutoplay);
19051		else{
19052			g_youtubeAPI.putVideo(g_temp.youtubeInnerID, videoID, "100%", "100%", isAutoplay);
19053		}
19054		
19055		g_activePlayerType = "youtube";
19056	}
19057	
19058	
19059	/**
19060	 * play vimeo
19061	 */
19062	this.playVimeo = function(videoID, isAutoplay){
19063		
19064		if(typeof isAutoplay == "undefined")
19065			var isAutoplay = true;
19066		
19067		stopAndHidePlayers("vimeo");
19068		
19069		g_objVimeo.show();
19070
19071		g_vimeoAPI.putVideo(g_temp.vimeoPlayerID, videoID, "100%", "100%", isAutoplay);
19072		
19073		/*
19074		if(g_vimeoAPI.isPlayerReady() && g_temp.standAloneMode == true){
19075			g_vimeoAPI.changeVideo(videoID, isAutoplay);
19076		}
19077		else
19078			g_vimeoAPI.putVideo(g_temp.vimeoPlayerID, videoID, "100%", "100%", isAutoplay);
19079		 */
19080		
19081		g_activePlayerType = "vimeo";
19082
19083	}
19084	
19085	
19086	/**
19087	 * play html5 video
19088	 */
19089	this.playHtml5Video = function(ogv, webm, mp4, posterImage, isAutoplay){
19090		
19091		if(typeof isAutoplay == "undefined")
19092			var isAutoplay = true;
19093				
19094		stopAndHidePlayers("html5");
19095		
19096		g_objHtml5.show();
19097		
19098		//trace(posterImage);
19099		
19100		var data = {
19101				ogv: ogv, 
19102				webm: webm, 
19103				mp4: mp4, 
19104				posterImage: posterImage 
19105			};
19106		
19107		g_html5API.putVideo(g_temp.html5PlayerID, data, "100%", "100%", isAutoplay);
19108		
19109		g_activePlayerType = "html5";
19110
19111	}
19112
19113	/**
19114	 * play sound cloud
19115	 */
19116	this.playSoundCloud = function(trackID, isAutoplay){
19117		
19118		if(typeof isAutoplay == "undefined")
19119			var isAutoplay = true;
19120		
19121		stopAndHidePlayers("soundcloud");
19122		
19123		g_objSoundCloud.show();
19124		
19125		g_soundCloudAPI.putSound(g_temp.soundCloudPlayerID, trackID, "100%", "100%", isAutoplay);
19126
19127		g_activePlayerType = "soundcloud";
19128	
19129	}
19130	
19131	
19132	/**
19133	 * play sound cloud
19134	 */
19135	this.playWistia = function(videoID, isAutoplay){
19136		
19137		if(typeof isAutoplay == "undefined")
19138			var isAutoplay = true;
19139		
19140		stopAndHidePlayers("wistia");
19141		
19142		g_objWistia.show();
19143		
19144		g_wistiaAPI.putVideo(g_temp.wistiaPlayerID, videoID, "100%", "100%", isAutoplay);
19145	
19146		g_activePlayerType = "wistia";
19147
19148	}
19149	
19150}
19151
19152
19153var g_ugYoutubeAPI = new UGYoutubeAPI();
19154var g_ugVimeoAPI = new UGVimeoAPI();
19155var g_ugHtml5MediaAPI = new UGHtml5MediaAPI();
19156var g_ugSoundCloudAPI = new UGSoundCloudAPI();
19157var g_ugWistiaAPI = new UGWistiaAPI();
19158
19159
19160	/**
19161	 * prototype gallery funciton
19162	 */
19163	jQuery.fn.unitegallery = function(options){
19164		var element = jQuery(this);
19165		var galleryID = "#" + element.attr("id");
19166		
19167		if(!options)
19168			var options = {};
19169				
19170		var objGallery = new UniteGalleryMain();
19171		objGallery.run(galleryID, options);
19172		
19173		var api = new UG_API(objGallery);
19174		
19175		return(api);
19176	}
19177
19178	
19179	/**
19180	 * check for min jquery version
19181	 */
19182	function ugCheckForMinJQueryVersion(){
19183		
19184		var isMinJQuery = g_ugFunctions.checkMinJqueryVersion("1.8.0");
19185		
19186		if(isMinJQuery == false)
19187			throw new Error("The gallery can run from jquery 1.8 You have jQuery "+jQuery.fn.jquery+" Please update your jQuery library.");
19188	}
19189	
19190	
19191	/**
19192	 * check for errors function
19193	 */
19194	function ugCheckForErrors(galleryID, type){
19195
19196		/**
19197		 * check for jquery presents
19198		 */
19199		function checkForJqueryPresents(){
19200			if(typeof jQuery == "undefined")
19201				throw new Error("jQuery library not included");
19202		}
19203		
19204		/**
19205		 * check for double jquery error
19206		 */
19207		function checkForDoubleJQuery(){
19208
19209			if(typeof jQuery.fn.unitegallery == "function")
19210				return(true);
19211			
19212			var errorMessage = "You have some jquery.js library include that comes after the gallery files js include.";
19213			errorMessage += "<br> This include eliminates the gallery libraries, and make it not work.";
19214			
19215			if(type == "cms"){
19216				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.";
19217				errorMessage += "<br>&nbsp;&nbsp;&nbsp; 2. Find the double jquery.js include and remove it.";
19218			}else{
19219				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.";			
19220			}
19221			
19222			
19223			throw new Error(errorMessage);
19224		}
19225		
19226		try{
19227			if(type == "jquery"){
19228				checkForJqueryPresents();
19229				ugCheckForMinJQueryVersion();
19230			}else{
19231				ugCheckForMinJQueryVersion();
19232				checkForDoubleJQuery();
19233			}
19234			
19235		}catch(objError){
19236			
19237			var message = objError.message;
19238			message = "Unite Gallery Error: "+ message;
19239			message = "<div style='font-size:16px;color:#BC0C06;max-width:900px;border:1px solid red;padding:10px;'>" + message + "</div>"
19240			
19241			if(type == "jquery"){
19242				var objGallery = document.getElementById(galleryID);
19243				objGallery.innerHTML = message;
19244				objGallery.style.display = "block";
19245			}
19246			else
19247				jQuery(galleryID).show().html(message);
19248			
19249			return(false);
19250		}
19251		
19252		return(true);
19253	}
19254
19255	
19256function UniteGalleryMain(){
19257	
19258	var t = this;
19259	var g_galleryID;
19260	var g_objGallery = jQuery(t), g_objWrapper, g_objParent;
19261	var g_objThumbs, g_objSlider, g_functions = new UGFunctions(), g_objTabs;
19262	var g_arrItems = [], g_numItems, g_selectedItem = null, g_selectedItemIndex = -1;
19263	var g_objTheme, g_objCache = {};
19264	
19265	this.events = {
19266			ITEM_CHANGE: "item_change",
19267			SIZE_CHANGE: "size_change",
19268			ENTER_FULLSCREEN: "enter_fullscreen",
19269			EXIT_FULLSCREEN: "exit_fullscreen",
19270			START_PLAY: "start_play",
19271			STOP_PLAY: "stop_play",
19272			PAUSE_PLAYING: "pause_playing",
19273			CONTINUE_PLAYING: "continue_playing",
19274			SLIDER_ACTION_START: "slider_action_start",
19275			SLIDER_ACTION_END: "slider_action_end",
19276			ITEM_IMAGE_UPDATED: "item_image_updated",
19277			GALLERY_KEYPRESS: "gallery_keypress",
19278			GALLERY_BEFORE_REQUEST_ITEMS: "gallery_before_request_items",	//before ajax load items
19279			OPEN_LIGHTBOX:"open_lightbox",
19280			CLOSE_LIGHTBOX:"close_lightbox"			
19281	};
19282	
19283	
19284	//set the default gallery options
19285	var g_options = {				
19286			gallery_width:900,							//gallery width		
19287			gallery_height:500,							//gallery height
19288			
19289			gallery_min_width: 150,						//gallery minimal width when resizing
19290			gallery_min_height: 100,					//gallery minimal height when resizing
19291			
19292			gallery_theme:"default",					//default,compact,grid,slider - select your desired theme from the list of themes.
19293			gallery_skin:"default",						//default, alexis etc... - the global skin of the gallery. Will change all gallery items by default.
19294			
19295			gallery_images_preload_type:"minimal",		//all , minimal , visible - preload type of the images.
19296														//minimal - only image nabours will be loaded each time.
19297														//visible - visible thumbs images will be loaded each time.
19298														//all - load all the images first time.
19299			
19300			gallery_autoplay:false,						//true / false - begin slideshow autoplay on start
19301			gallery_play_interval: 3000,				//play interval of the slideshow
19302			gallery_pause_on_mouseover: true,			//true,false - pause on mouseover when playing slideshow true/false
19303			
19304			gallery_mousewheel_role:"zoom",				//none, zoom, advance
19305			gallery_control_keyboard: true,				//true,false - enable / disble keyboard controls
19306			gallery_carousel:true,						//true,false - next button on last image goes to first image.
19307			
19308			gallery_preserve_ratio: true,				//true, false - preserver ratio when on window resize
19309			gallery_background_color: "",				//set custom background color. If not set it will be taken from css.
19310			gallery_debug_errors:false,					//show error message when there is some error on the gallery area.
19311			gallery_shuffle:false,						//randomise position of items at start.
19312			gallery_urlajax:null,						//ajax url for requesting new items etc.
19313			gallery_enable_tabs: false,					//enable/disable category tabs
19314			gallery_enable_cache: true,					//enable caching items
19315			gallery_initial_catid: ""					//initial category id (for caching)
19316	};
19317	
19318	//gallery_control_thumbs_mousewheel
19319	
19320	var g_temp = {					//temp variables
19321		objCustomOptions:{},
19322		isAllItemsPreloaded:false,	//flag that tells that all items started preloading
19323		isFreestyleMode:false,		//no special html additions
19324		lastWidth:0,
19325		lastHeigh:0,
19326		handleResize: null,
19327		isInited: false,
19328		isPlayMode: false,
19329		isPlayModePaused: false,
19330		playTimePassed: 0,
19331		playTimeLastStep: 0,
19332		playHandle: "",
19333		playStepInterval: 33,
19334		objProgress: null,
19335		isFakeFullscreen: false,
19336		thumbsType:null,
19337		isYoutubePresent:false,			//flag if present youtube items
19338		isVimeoPresent:false,			//flag if present vimeo items
19339		isHtml5VideoPresent:false,		//flag if present html5 video items
19340		isSoundCloudPresent:false,		//flag if present soundcloud items
19341		isWistiaPresent: false,			//flag if some wistia movie present
19342		resizeDelay: 100,
19343		isRunFirstTime: true,
19344		originalOptions: {},
19345		funcCustomHeight: null			//custom height function, set by the theme if needed
19346	};
19347	
19348	
19349	
19350	function __________INIT_GALLERY_______(){};
19351	
19352	/**
19353	 * get theme function from theme name
19354	 */
19355	function getThemeFunction(themeName){
19356		 var themeFunction = themeName;
19357		if(themeFunction.indexOf("UGTheme_") == -1)
19358			 themeFunction = "UGTheme_" + themeFunction;
19359		
19360		return(themeFunction);
19361	}
19362
19363	/**
19364	 * init the theme
19365	 */
19366	function initTheme(objCustomOptions){
19367		 
19368		//set theme function:
19369		 if(objCustomOptions.hasOwnProperty("gallery_theme"))
19370			 g_options.gallery_theme = objCustomOptions.gallery_theme;
19371		 else{
19372			 var defaultTheme = g_options.gallery_theme;
19373			 if(g_ugFunctions.isThemeRegistered(defaultTheme) == false)
19374				 g_options.gallery_theme = g_ugFunctions.getFirstRegisteredTheme();
19375		 }
19376		 
19377		 var themeFunction = getThemeFunction(g_options.gallery_theme);
19378		 
19379		 try{
19380			 g_options.gallery_theme = eval(themeFunction);
19381		 }catch(e){
19382			 //check registered themes
19383		 };
19384		 
19385		 g_options.gallery_theme = eval(themeFunction);
19386		 
19387		 //init the theme
19388		 g_objTheme = new g_options.gallery_theme();
19389		 g_objTheme.init(t, objCustomOptions);
19390	}
19391	
19392	
19393	/**
19394	 * reset all the options for the second time run
19395	 */
19396	function resetOptions(){
19397	   	 
19398		 g_options = jQuery.extend({}, g_temp.originalOptions);
19399		 
19400		 g_selectedItemIndex = -1;
19401		 g_selectedItem = null;
19402		 g_objSlider = undefined;
19403		 g_objThumbs = undefined;
19404		 g_objSlider = undefined; 
19405	}
19406	
19407	
19408	/**
19409	 * check for some errors and fire error if needed
19410	 */
19411	function checkForStartupErrors(){
19412		
19413		//protection agains old jquery version
19414		try{
19415			ugCheckForMinJQueryVersion();
19416		}catch(e){
19417			throwErrorShowMessage(e.message);
19418		}
19419		
19420		//protection against some jquery ui function change
19421	     if(typeof g_objWrapper.outerWidth() == "object")
19422	    	 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.");
19423	     
19424	     //check for late jquery include
19425	     setTimeout(function(){ugCheckForErrors(g_galleryID, "cms")} , 5000);
19426	     
19427	}
19428	
19429	
19430	
19431	/**
19432	 *  the gallery
19433	 */
19434	function runGallery(galleryID, objCustomOptions, htmlItems, cacheID){
19435			
19436			var isCustomOptions = (typeof objCustomOptions == "object");
19437			
19438			if(isCustomOptions)
19439		      g_temp.objCustomOptions = objCustomOptions;
19440			 			 
19441		     if(g_temp.isRunFirstTime == true){
19442				
19443		    	 g_galleryID = galleryID;
19444				 g_objWrapper = jQuery(g_galleryID);
19445				 if(g_objWrapper.length == 0){
19446					 trace("div with id: "+g_galleryID+" not found");
19447					 return(false);
19448				 }
19449
19450				 g_objParent = g_objWrapper.parent();
19451				 
19452				 checkForStartupErrors();
19453				 
19454				 g_temp.originalOptions = jQuery.extend({}, g_options);
19455				 
19456				 //merge options
19457				 if(isCustomOptions)
19458					 g_options = jQuery.extend(g_options, objCustomOptions);
19459				 
19460				 //cache items
19461				 if(g_options.gallery_enable_cache == true && g_options.gallery_initial_catid)
19462					 cacheItems(g_options.gallery_initial_catid);
19463				
19464				 //set size class
19465				 t.setSizeClass();
19466				 
19467				 //fill arrItems
19468				 var objItems = g_objWrapper.children();
19469				 
19470				 fillItemsArray(objItems);
19471				 loadAPIs();
19472				 
19473				 //hide images:
19474				 g_objWrapper.find("img").fadeTo(0,0).hide();
19475				 g_objWrapper.show();
19476		
19477				 clearInitData();
19478		    	 
19479		     }else{		//reset options - not first time run
19480		    	 
19481		    	 t.destroy();
19482		    	 
19483		    	 resetOptions();
19484
19485		    	 g_options = jQuery.extend(g_options, g_temp.objCustomOptions);
19486	    		 
19487		    	 if(htmlItems){
19488		    		 
19489		    		 //cache items
19490		    		 if(cacheID && g_options.gallery_enable_cache == true)
19491		    			 cacheItems(cacheID, htmlItems);
19492		    		 
19493		    		 if(htmlItems == "noitems"){
19494		    			 showErrorMessage("No items in this category","");
19495		    			 return(false);
19496			    	 }
19497		    		 
19498		    		 g_objWrapper.html(htmlItems);
19499		    		 
19500		    		 var objItems = g_objWrapper.children();
19501		    		 fillItemsArray(objItems);
19502					 
19503		    		 loadAPIs();
19504					 
19505					 g_objWrapper.children().fadeTo(0,0).hide();
19506					 
19507					 g_objWrapper.show();
19508					 clearInitData();
19509		    	 }
19510		     
19511		     }
19512		     
19513			 //init tabs
19514			 if(g_temp.isRunFirstTime == true && g_options.gallery_enable_tabs == true){
19515				 g_objTabs = new UGTabs();
19516				 g_objTabs.init(t, g_options);
19517			 }
19518			 
19519			 //modify and verify the params
19520			 if(isCustomOptions)
19521				 modifyInitParams(g_temp.objCustomOptions);
19522			 			 
19523			 validateParams();
19524			 
19525			 //shuffle items
19526			 if(g_options.gallery_shuffle == true)
19527				 t.shuffleItems();
19528			 			 
19529			 //init the theme
19530			 initTheme(g_temp.objCustomOptions);
19531			 			 				 
19532			 //set gallery html elements
19533			 setGalleryHtml();
19534
19535			 //set html properties to all elements
19536			 setHtmlObjectsProperties();
19537			 
19538			 var galleryWidth = g_objWrapper.width();
19539			 
19540			 if(galleryWidth == 0){
19541				 g_functions.waitForWidth(g_objWrapper, runGalleryActually);
19542			 }else
19543				 runGalleryActually();
19544			 
19545	}
19546	
19547	
19548	/**
19549	 * actually run the gallery
19550	 */
19551	function runGalleryActually(){
19552		 
19553		t.setSizeClass();
19554		
19555		if(g_temp.isFreestyleMode == false){
19556			 	
19557			 if(g_options.gallery_preserve_ratio == true)
19558				 setHeightByOriginalRatio();
19559		 }
19560		 
19561		 g_objTheme.run();
19562		 
19563		 if(g_objTabs && g_temp.isRunFirstTime)
19564			 g_objTabs.run();
19565		 
19566		 preloadBigImages();
19567		 
19568		 initEvents();
19569		 
19570		 //select first item
19571		 if(g_numItems > 0) 
19572			 t.selectItem(0);
19573		 
19574		 
19575		 //set autoplay
19576		 if(g_options.gallery_autoplay == true)
19577			 t.startPlayMode();
19578		 
19579		 g_temp.isRunFirstTime = false;
19580		
19581	}
19582	
19583	
19584	/**
19585	 * 
19586	 * show error message
19587	 */
19588	function showErrorMessage(message, prefix){
19589
19590		if(typeof prefix == "undefined")
19591			var prefix = "<b>Unite Gallery Error: </b>";
19592				
19593		message = prefix + message;
19594		
19595		var html = "<div class='ug-error-message-wrapper'><div class='ug-error-message'>" + message + "</div></div>";
19596		
19597		g_objWrapper.children().remove();
19598		
19599		g_objWrapper.html(html);
19600		g_objWrapper.show();		
19601	}
19602	
19603	/**
19604	 * show error message and throw error
19605	 */
19606	function throwErrorShowMessage(message){
19607		showErrorMessage(message);
19608		throw new Error(message);
19609	}
19610	
19611	
19612	/**
19613	 * 
19614	 * @param objParams
19615	 */
19616	 function modifyInitParams(){
19617		 
19618		 //set default for preloading
19619		 if(!g_options.gallery_images_preload_type)
19620			 g_options.gallery_images_preload_type = "minimal";
19621		 
19622		 //normalize gallery min height and width
19623		 if(g_options.gallery_min_height == undefined || g_options.gallery_height < g_options.gallery_min_height){
19624			 g_options.gallery_min_height = 0;
19625		 }
19626		 
19627		 if(g_options.gallery_min_width == undefined || g_options.gallery_width < g_options.gallery_min_width){
19628			 g_options.gallery_min_width = 0;
19629		 }
19630		 
19631	 }
19632
19633	
19634	/**
19635	 * validate the init parameters
19636	 */
19637	 function validateParams(){
19638		 
19639		 //validate theme:
19640		 if(!g_options.gallery_theme)
19641			 throw new Error("The gallery can't run without theme");
19642		 		 
19643		 //if(typeof g_options.theme != "function")
19644			 //throw new Error("Wrong theme function: " + g_options.theme.toString());
19645		 
19646		 //validate height and width
19647		 if(jQuery.isNumeric(g_options.gallery_height) && g_options.gallery_height < g_options.gallery_min_height)
19648			 throw new Error("The <b>gallery_height</b> option must be bigger then <b>gallery_min_height option</b>");
19649		 
19650		 if(g_options.gallery_width < g_options.gallery_min_width)
19651			 throw new Error("The <b>gallery_width</b> option must be bigger then <b>gallery_min_width option</b>");
19652		 
19653		 
19654	 }
19655	 
19656	 
19657	 /**
19658	 * set gallery html
19659	 */
19660	function setGalleryHtml(){
19661		
19662		 //add classes and divs
19663		 g_objWrapper.addClass("ug-gallery-wrapper");
19664		 
19665		 g_objWrapper.append("<div class='ug-overlay-disabled' style='display:none'></div>");
19666		 
19667		 t.setSizeClass();
19668	}
19669	
19670	
19671	/**
19672	 * if the thumbs panel don't exists, delete initial images from dom
19673	 */
19674	function clearInitData(){
19675		
19676		var objItems = g_objWrapper.children().remove();
19677	}
19678	
19679	
19680	/**
19681	 * store last gallery size
19682	 */
19683	function storeLastSize(){
19684		var objSize = t.getSize();
19685		
19686		g_temp.lastWidth = objSize.width;
19687		g_temp.lastHeight = objSize.height;
19688	}
19689	
19690	
19691	/**
19692	 * set gallery height by original ratio
19693	 */
19694	function setHeightByOriginalRatio(){
19695		
19696		var objSize = t.getSize();
19697				
19698		var ratio = objSize.width / objSize.height;
19699		
19700		if(ratio != objSize.orig_ratio){
19701			
19702			var newHeight = objSize.width / objSize.orig_ratio;
19703			newHeight = Math.round(newHeight);
19704			
19705			if(newHeight < g_options.gallery_min_height)
19706				newHeight = g_options.gallery_min_height;
19707			
19708			g_objWrapper.height(newHeight);
19709		}
19710	
19711	}
19712
19713	
19714	/**
19715	 * set properties of the html objects
19716	 */
19717	function setHtmlObjectsProperties(){
19718		   
19719			var optionWidth = g_functions.getCssSizeParam(g_options.gallery_width);
19720			
19721		   //set size		
19722		   var objCss = {
19723				    //"width":optionWidth,		//make it work within tabs
19724				    "max-width":optionWidth,
19725					"min-width":g_functions.getCssSizeParam(g_options.gallery_min_width)
19726			};
19727		   
19728		   if(g_temp.isFreestyleMode == false){
19729			   
19730			   var galleryHeight = g_functions.getCssSizeParam(g_options.gallery_height);
19731			   objCss["height"] = galleryHeight;
19732		   
19733		   }else{
19734			   objCss["overflow"] = "visible";			   
19735		   }
19736		   
19737		   //set background color
19738		   if(g_options.gallery_background_color)
19739			   objCss["background-color"] = g_options.gallery_background_color;
19740		   
19741		   
19742		   g_objWrapper.css(objCss);
19743		   
19744	}
19745
19746	
19747	/**
19748	 * fill items array from images object
19749	 */
19750	function fillItemsArray(arrChildren){
19751		
19752		g_arrItems = [];
19753		
19754		var isMobile = t.isMobileMode();
19755		
19756		 var numIndex = 0;
19757		 
19758		 for(var i=0;i<arrChildren.length;i++){
19759			 var objChild = jQuery(arrChildren[i]);
19760			 
19761			 var tagname = objChild.prop("tagName").toLowerCase();
19762			 
19763			 //handle link wrapper
19764			 var itemLink = "";
19765			 if(tagname == "a"){
19766				 itemLink = objChild.attr("href");
19767				 objChild = objChild.children();
19768				 var tagname = objChild.prop("tagName").toLowerCase();				 
19769			 }
19770			 
19771			 var itemType = objChild.data("type");
19772			 if(itemType == undefined)
19773				 itemType = "image";
19774			 
19775			 var objItem = {};
19776			 objItem.type = itemType;
19777			 
19778			 if(tagname == "img"){
19779				 
19780				 //protection agains lasy load
19781				 var lasyLoadSrc = objChild.data("lazyload-src");
19782				 if(lasyLoadSrc && lasyLoadSrc != ""){
19783					 objChild.attr("src", lasyLoadSrc);
19784					 jQuery.removeData(objChild, "lazyload-src");
19785				 }
19786				 
19787				 //src is thumb
19788				 var urlImage = objChild.data("image");
19789				 var urlThumb = objChild.data("thumb");
19790				 
19791				 if(typeof(urlImage) == "undefined")
19792					 urlImage = null;
19793				 
19794				 if(typeof(urlThumb) == "undefined")
19795					 urlThumb = null;
19796				 
19797				 var imageSrc = objChild.attr("src");
19798				 
19799				 if(!urlImage)
19800					 urlImage = imageSrc;
19801					 
19802				 if(!urlThumb)
19803					 urlThumb = imageSrc;
19804				 
19805				 if(!urlThumb)
19806					 urlThumb = urlImage;
19807				 
19808				 if(!urlImage)
19809					 urlImage = urlThumb;
19810				 
19811				 
19812				 objItem.urlThumb = urlThumb;
19813				 objItem.urlImage = urlImage;
19814				 				 
19815				 objItem.title = objChild.attr("alt");
19816				 
19817				 //always set thumb image to object
19818				 objItem.objThumbImage = objChild;
19819				 
19820				 objItem.objThumbImage.attr("src", objItem.urlThumb);
19821				 
19822			 }else{
19823				 
19824				 if(itemType == "image"){
19825					 trace("Problematic gallery item found:");
19826					 trace(objChild);
19827					 trace("Please look for some third party js script that could add this item to the gallery");
19828					 throw new Error("The item should not be image type");
19829				 }
19830				 
19831				 objItem.urlThumb = objChild.data("thumb");
19832				 objItem.title = objChild.data("title");
19833				 objItem.objThumbImage = null;
19834				 objItem.urlImage = objChild.data("image");
19835			 }
19836			 
19837			 
19838			 //check mobile version images
19839			 if(isMobile == true){
19840				 
19841				 var urlThumbMobile = objChild.data("thumb-mobile");
19842				 if(typeof urlThumbMobile != "undefined" && urlThumbMobile != ""){
19843					 objItem.urlThumb = urlThumbMobile;
19844	 			 	 
19845					 if(tagname == "img")
19846	 					 objChild.attr("src",objItem.urlThumb);
19847				 }
19848				 
19849				 var urlImageMobile = objChild.data("image-mobile");
19850				 if(typeof urlImageMobile != "undefined" && urlImageMobile != "")
19851					 objItem.urlImage = urlImageMobile;
19852			 }
19853			 
19854			 objItem.link = itemLink;
19855			 
19856			 //get description:
19857			 objItem.description = objChild.attr("title");
19858			 if(!objItem.description)				 
19859				 objItem.description = objChild.data("description");
19860			 
19861			 if(!objItem.description)
19862				 objItem.description = "";
19863			 
19864			 objItem.isLoaded = false;
19865			 objItem.isThumbImageLoaded = false;	//if the image loaded or error load
19866			 objItem.objPreloadImage = null;
19867			 objItem.isBigImageLoadStarted = false;
19868			 objItem.isBigImageLoaded = false;
19869			 objItem.isBigImageLoadError = false;			 
19870			 objItem.imageWidth = 0;
19871			 objItem.imageHeight = 0;
19872			 
19873			 //set thumb size
19874			 objItem.thumbWidth = 0;
19875			 objItem.thumbHeight = 0;
19876			 objItem.thumbRatioByWidth = 0;
19877			 objItem.thumbRatioByHeight = 0;
19878			 
19879			 var dataWidth = objChild.data("width");
19880			 var dataHeight = objChild.data("height");
19881			 if(dataWidth && typeof dataWidth == "number" && dataHeight && typeof dataHeight == "number"){
19882				 objItem.thumbWidth = dataWidth;
19883				 objItem.thumbHeight = dataHeight;
19884				 objItem.thumbRatioByWidth = dataWidth / dataHeight;
19885				 objItem.thumbRatioByHeight = dataHeight / dataWidth;
19886			 }
19887			 
19888			 objItem.addHtml = null;
19889			 
19890			 var isImageMissing = (objItem.urlImage == undefined || objItem.urlImage == "");
19891			 var isThumbMissing = (objItem.urlThumb == undefined || objItem.urlThumb == "");
19892			 
19893			 switch(objItem.type){
19894			 	case "youtube":			 		
19895					 objItem.videoid = objChild.data("videoid");
19896			 		 
19897					 if(isImageMissing || isThumbMissing){
19898						 
19899						 var objImages = g_ugYoutubeAPI.getVideoImages(objItem.videoid);
19900					 		
19901				 		 //set preview image
19902				 		 if(isImageMissing)
19903				 			objItem.urlImage = objImages.preview;
19904				 		
19905				 		 //set thumb image
19906				 		 if(isThumbMissing){
19907				 			 	objItem.urlThumb = objImages.thumb;
19908				 				
19909				 			 	 if(tagname == "img")
19910				 					 objChild.attr("src",objItem.urlThumb);
19911				 		 }
19912						 
19913					 }
19914					 
19915					 g_temp.isYoutubePresent = true;
19916				break;
19917			 	case "vimeo":
19918			 		
19919					objItem.videoid = objChild.data("videoid");
19920										
19921					g_temp.isVimeoPresent = true;
19922			 	break;
19923			 	case "html5video":
19924			 		objItem.videoogv = objChild.data("videoogv");
19925			 		objItem.videowebm = objChild.data("videowebm");
19926			 		objItem.videomp4 = objChild.data("videomp4");
19927			 		
19928			 		g_temp.isHtml5VideoPresent = true;
19929			 	break;
19930			 	case "soundcloud":
19931			 		objItem.trackid = objChild.data("trackid");
19932			 		g_temp.isSoundCloudPresent = true;
19933			 	break;
19934			 	case "wistia":
19935					 objItem.videoid = objChild.data("videoid");
19936					 g_temp.isWistiaPresent = true;
19937			 	break;
19938			 	case "custom":
19939					var objChildImage = objChild.children("img");
19940			 		
19941					if(objChildImage.length){
19942						objChildImage = jQuery(objChildImage[0]);
19943						
19944					    objItem.urlThumb = objChildImage.attr("src");
19945					    objItem.title = objChildImage.attr("alt");
19946					    objItem.objThumbImage = objChildImage;
19947			 		}
19948			 		
19949					//add additional html
19950					var objChildren = objChild.children().not("img:first-child");
19951			 		
19952					if(objChildren.length)
19953						objItem.addHtml = objChildren.clone();
19954			 		
19955			 	break;
19956			 }
19957			
19958			 //clear not needed attributes
19959			 if(objItem.objThumbImage){
19960				 objItem.objThumbImage.removeAttr("data-description", "");
19961				 objItem.objThumbImage.removeAttr("data-image", "");				 
19962				 objItem.objThumbImage.removeAttr("data-thumb", "");				 
19963				 objItem.objThumbImage.removeAttr("title", "");				 
19964			 }
19965			 
19966			 objItem.index = numIndex;
19967			 g_arrItems.push(objItem);
19968			 numIndex++;
19969			 
19970		 }
19971		 
19972		 
19973		 g_numItems = g_arrItems.length;
19974		 
19975	}
19976	
19977	
19978	/**
19979	 * load api's according presented item types
19980	 */
19981	function loadAPIs(){
19982		
19983		//load youtube api
19984		if(g_temp.isYoutubePresent)
19985			g_ugYoutubeAPI.loadAPI();
19986		
19987		if(g_temp.isVimeoPresent)
19988			g_ugVimeoAPI.loadAPI();
19989		
19990		if(g_temp.isHtml5VideoPresent)
19991			g_ugHtml5MediaAPI.loadAPI();
19992		
19993		if(g_temp.isSoundCloudPresent)
19994			g_ugSoundCloudAPI.loadAPI();
19995		
19996		if(g_temp.isWistiaPresent)
19997			g_ugWistiaAPI.loadAPI();
19998		
19999	}
20000	
20001	
20002	/**
20003	 * preload big images
20004	 */
20005	function preloadBigImages(){
20006		
20007		//check and fix preload type
20008		if(g_options.gallery_images_preload_type == "visible" && !g_objThumbs)
20009			g_options.gallery_images_preload_type = "minimal";
20010		
20011		if(g_temp.isAllItemsPreloaded == true)
20012			return(true);
20013		
20014		switch(g_options.gallery_images_preload_type){
20015			default:
20016			case "minimal":
20017			break;
20018			case "all":
20019				
20020				jQuery(g_arrItems).each(function(){	
20021					preloadItemImage(this);			
20022				});			
20023				
20024			break;
20025			case "visible":
20026				jQuery(g_arrItems).each(function(){		
20027					var objItem = this;
20028					var isVisible = g_objThumbs.isItemThumbVisible(objItem);
20029					
20030					if(isVisible == true)
20031						preloadItemImage(objItem);
20032				});
20033				
20034			break;
20035		}
20036				
20037	}
20038	
20039	/**
20040	 * check if item needed to preload and preload it
20041	 */
20042	function checkPreloadItemImage(objItem){
20043		
20044		if(objItem.isBigImageLoadStarted == true ||
20045				   objItem.isBigImageLoaded == true || 
20046				   objItem.isBigImageLoadError == true){
20047					return(false);			
20048		}
20049		
20050		switch(g_options.gallery_images_preload_type){
20051			default:
20052			case "minimal":
20053			break;
20054			case "all":			
20055					preloadItemImage(objItem);							
20056			break;
20057			case "visible":
20058				var isVisible = g_objThumbs.isItemThumbVisible(objItem);					
20059					if(isVisible == true)
20060						preloadItemImage(objItem);				
20061			break;
20062		}
20063		
20064	}
20065	
20066	/**
20067	 * preload item image
20068	 */
20069	function preloadItemImage(objItem){
20070		
20071		if(objItem.isBigImageLoadStarted == true ||
20072		   objItem.isBigImageLoaded == true || 
20073		   objItem.isBigImageLoadError == true){
20074			return(true);			
20075		}
20076		
20077		var imageUrl = objItem.urlImage;
20078		if(imageUrl == "" || imageUrl == undefined){
20079			objItem.isBigImageLoadError = true;
20080			return(false);
20081		}
20082		
20083		objItem.isBigImageLoadStarted = true;
20084				
20085		objItem.objPreloadImage = jQuery('<img/>').attr("src", imageUrl);
20086		objItem.objPreloadImage.data("itemIndex", objItem.index);
20087		
20088		//set image load event (not that reliable)
20089		objItem.objPreloadImage.on("load", t.onItemBigImageLoaded);
20090		
20091		//set load error event
20092		objItem.objPreloadImage.on( "error", function(){
20093			var objImage = jQuery(this);
20094			var itemIndex = objImage.data("itemIndex");
20095			var objItem = g_arrItems[itemIndex];
20096			
20097			//update error:
20098			objItem.isBigImageLoadError = true;
20099			objItem.isBigImageLoaded = false;
20100			
20101			//print error
20102			var imageUrl = jQuery(this).attr("src");
20103			console.log("Can't load image: "+ imageUrl);
20104			
20105			//try to load the image again
20106			g_objGallery.trigger(t.events.ITEM_IMAGE_UPDATED, [itemIndex, objItem.urlImage]);
20107			objItem.objThumbImage.attr("src", objItem.urlThumb);
20108			
20109		});
20110		
20111		//check the all items started preloading flag
20112		checkAllItemsStartedPreloading();
20113		
20114	}
20115	
20116	
20117	/**
20118	 * on item big image loaded event function. 
20119	 * Update image size and that the image has been preloaded
20120	 * can be called from another objects like the slider
20121	 */
20122	this.onItemBigImageLoaded = function(event, objImage){
20123				
20124		if(!objImage)
20125			var objImage = jQuery(this);
20126		
20127		var itemIndex = objImage.data("itemIndex");
20128		
20129		var objItem = g_arrItems[itemIndex];
20130		
20131		objItem.isBigImageLoaded = true;
20132		
20133		//get size with fallback function
20134		var objSize = g_functions.getImageOriginalSize(objImage);
20135		
20136		objItem.imageWidth = objSize.width;
20137		objItem.imageHeight = objSize.height;		
20138	}
20139	
20140	/**
20141	 * check and fill image size in item object
20142	 */
20143	this.checkFillImageSize = function(objImage, objItem){
20144		
20145		if(!objItem){
20146			var itemIndex = objImage.data("itemIndex");
20147			if(itemIndex === undefined)
20148				throw new Error("Wrong image given to gallery.checkFillImageSize");
20149			
20150			var objItem = g_arrItems[itemIndex];
20151		}
20152		
20153		var objSize = g_functions.getImageOriginalSize(objImage);
20154		
20155		objItem.imageWidth = objSize.width;
20156		objItem.imageHeight = objSize.height;		
20157	}
20158	
20159	
20160	/**
20161	 * preload next images near current item
20162	 */
20163	function preloadNearBigImages(objItem){
20164		
20165		if(g_temp.isAllItemsPreloaded == true)
20166			return(false);
20167		
20168		if(!objItem)
20169			var objItem = g_selectedItem;
20170		
20171		if(!objItem)
20172			return(true);
20173			
20174		var currentIndex = objItem.index;
20175		var lastItemIndex = currentIndex - 1;
20176		var nextItemIndex = currentIndex + 1;
20177		
20178		if(lastItemIndex > 0)
20179			preloadItemImage(g_arrItems[lastItemIndex]);
20180		
20181		if(nextItemIndex < g_numItems)
20182			preloadItemImage(g_arrItems[nextItemIndex]);
20183			
20184	}
20185	
20186	
20187	/**
20188	 * check that all items started preloading, if do, set 
20189	 * flag g_temp.isAllItemsPreloaded to true
20190	 */
20191	function checkAllItemsStartedPreloading(){
20192		
20193		if(g_temp.isAllItemsPreloaded == true)
20194			return(false);
20195		
20196		//if some of the items not started, exit function:
20197		for(var index in g_arrItems){
20198			if(g_arrItems[index].isBigImageLoadStarted == false)
20199				return(false);
20200		}
20201		
20202		//if all started, set flag to true
20203		g_temp.isAllItemsPreloaded = true;	
20204	}
20205	
20206	
20207	/**
20208	 * set freestyle mode
20209	 */
20210	this.setFreestyleMode = function(){
20211		
20212		g_temp.isFreestyleMode = true;
20213	
20214	}
20215	
20216	
20217	/**
20218	 * attach thumbs panel to the gallery
20219	 */
20220	this.attachThumbsPanel = function(type, objThumbs){
20221		g_temp.thumbsType = type;
20222		g_objThumbs = objThumbs;
20223	}
20224	
20225	
20226	/**
20227	 * init the slider
20228	 */	
20229	this.initSlider = function(customOptions, optionsPrefix){
20230		 
20231		 //mix options with user options
20232		 if(!customOptions)
20233			 var customOptions = {};
20234		 		 
20235		 customOptions = jQuery.extend(g_temp.objCustomOptions, customOptions);
20236		 
20237		 g_objSlider = new UGSlider();		 
20238		 g_objSlider.init(t, customOptions, optionsPrefix);
20239	}
20240	
20241	
20242	function __________END_INIT_GALLERY_______(){};
20243	
20244	function __________EVENTS_____________(){};
20245
20246	
20247	/**
20248	 * on gallery mousewheel event handler, advance the thumbs
20249	 */
20250	this.onGalleryMouseWheel = function(event, delta, deltaX, deltaY){
20251		
20252		event.preventDefault();
20253		
20254		if(delta > 0)
20255			t.prevItem();
20256		else
20257			t.nextItem();
20258	}
20259	
20260	
20261	/**
20262	 * on mouse enter event
20263	 */
20264	function onSliderMouseEnter(event){
20265		
20266		if(g_options.gallery_pause_on_mouseover == true && t.isFullScreen() == false && g_temp.isPlayMode == true && g_objSlider && g_objSlider.isSlideActionActive() == false)
20267			t.pausePlaying();
20268	}
20269	
20270	
20271	/**
20272	 * on mouse move event
20273	 */
20274	function onSliderMouseLeave(event){
20275		
20276		if(g_options.gallery_pause_on_mouseover == true && g_temp.isPlayMode == true && g_objSlider && g_objSlider.isSlideActionActive() == false){
20277			
20278			var isStillLoading = g_objSlider.isCurrentSlideLoadingImage();
20279			
20280			if(isStillLoading == false)
20281				t.continuePlaying();
20282		}
20283		
20284	}
20285	
20286	
20287	/**
20288	 * on keypress - keyboard control
20289	 */
20290	function onKeyPress(event){
20291		 
20292		var obj = jQuery(event.target);
20293		if(obj.is("textarea") || obj.is("select") || obj.is("input"))
20294			return(true);
20295						
20296		 var keyCode = (event.charCode) ? event.charCode :((event.keyCode) ? event.keyCode :((event.which) ? event.which : 0));
20297		 
20298		 var wasAction = true;
20299		 
20300		 switch(keyCode){
20301			 case 39:	//right key
20302				 t.nextItem();
20303			 break;
20304			 case 37:	//left key
20305				 t.prevItem();
20306			 break;
20307			 default:
20308				 wasAction = false;
20309			 break; 
20310		 }
20311		 
20312		 //only first page gallery affected
20313		 
20314		 if(wasAction == true){
20315			 event.preventDefault();
20316			 event.stopPropagation();
20317			 event.stopImmediatePropagation();
20318		 }
20319		 
20320		g_objGallery.trigger(t.events.GALLERY_KEYPRESS, [keyCode,event]);
20321	}
20322	
20323	
20324	/**
20325	 * check that the gallery resized, if do, trigger onresize event
20326	 */
20327	function onGalleryResized(){
20328		
20329		var objSize = t.getSize();
20330		
20331		if(objSize.width == 0)	//fix hidden gallery change
20332			return(true);
20333		
20334		t.setSizeClass();
20335		
20336		var objSize = t.getSize();
20337				
20338		if(objSize.width != g_temp.lastWidth || objSize.height != g_temp.lastHeight){
20339			
20340			var heightWasSet = false;
20341			
20342			//set height with custom function (if exists)
20343			if(g_temp.funcCustomHeight){
20344				var newHeight = g_temp.funcCustomHeight(objSize);
20345				if(newHeight){
20346					g_objWrapper.height(newHeight);
20347					heightWasSet = true;
20348				}
20349			}
20350			
20351			if(heightWasSet == false && g_options.gallery_preserve_ratio == true && g_temp.isFreestyleMode == false)
20352				setHeightByOriginalRatio();
20353			
20354			storeLastSize();
20355			g_objGallery.trigger(t.events.SIZE_CHANGE);
20356			
20357		}
20358		
20359	}
20360
20361	
20362	/**
20363	 * on strip move event
20364	 * preload visible images if that option selected
20365	 */
20366	function onThumbsChange(event){
20367		
20368		//preload visible images 
20369		if(g_options.gallery_images_preload_type == "visible" && g_temp.isAllItemsPreloaded == false){
20370			preloadBigImages();
20371		}
20372		
20373	}
20374	
20375	
20376	/**
20377	 * on full screen change event
20378	 */
20379	function onFullScreenChange(){
20380		
20381		
20382		var isFullscreen = g_functions.isFullScreen();
20383		var event = isFullscreen ? t.events.ENTER_FULLSCREEN:t.events.EXIT_FULLSCREEN; 
20384
20385		 var fullscreenID = g_functions.getGlobalData("fullscreenID");
20386		 
20387		 //check if this gallery was affected
20388		 if(g_galleryID !== fullscreenID)
20389			 return(true);
20390		 		 
20391		 //add classes for the gallery
20392		 if(isFullscreen){
20393			 g_objWrapper.addClass("ug-fullscreen");
20394		 }else{
20395			 g_objWrapper.removeClass("ug-fullscreen");
20396		 }
20397
20398		 g_objGallery.trigger(event);
20399		 
20400		 onGalleryResized();
20401	}
20402	
20403	/**
20404	 * on big image updated, if needed - preload this item image
20405	 */
20406	function onItemImageUpdated(event, index){
20407		
20408		var objItem = t.getItem(index);		
20409		checkPreloadItemImage(objItem);		
20410	}
20411	
20412	/**
20413	 * on current slide image load end. If playing mode, begin playing again
20414	 */
20415	function onCurrentSlideImageLoadEnd(){
20416		
20417		if(t.isPlayMode() == true)
20418			t.continuePlaying();
20419	}
20420	
20421	
20422	/**
20423	 * init all events
20424	 */
20425	function initEvents(){
20426		
20427		//avoid annoyong firefox image dragging
20428		g_objWrapper.on("dragstart",function(event){
20429			event.preventDefault();
20430		});
20431		
20432		//on big image updated, if needed - preload this item image
20433		g_objGallery.on(t.events.ITEM_IMAGE_UPDATED, onItemImageUpdated);
20434		
20435		//init custom event on strip moving
20436		if(g_objThumbs){
20437			switch(g_temp.thumbsType){
20438				case "strip":
20439					jQuery(g_objThumbs).on(g_objThumbs.events.STRIP_MOVE, onThumbsChange);
20440				break;
20441				case "grid":
20442					jQuery(g_objThumbs).on(g_objThumbs.events.PANE_CHANGE, onThumbsChange);
20443				break;
20444			}
20445		}
20446		
20447		//init mouse wheel
20448		if(g_options.gallery_mousewheel_role == "advance" && g_temp.isFreestyleMode == false)
20449			g_objWrapper.on("mousewheel", t.onGalleryMouseWheel);
20450		
20451		 //on resize event
20452		 storeLastSize();
20453		 
20454		 jQuery(window).resize(function(){
20455			 g_objWrapper.css("width","auto");
20456			 g_functions.whenContiniousEventOver("gallery_resize", onGalleryResized, g_temp.resizeDelay);
20457		 });
20458		 
20459		 //check resize once in a time, start from 10 seconds
20460		 setTimeout(function(){
20461			 setInterval(onGalleryResized, 2000);			 
20462		 }, 10000);
20463		 
20464		 
20465		 //fullscreen:
20466		 g_functions.addFullScreenChangeEvent(onFullScreenChange);
20467		 
20468		 //on slider item changed event
20469		 if(g_objSlider){
20470			 
20471			 jQuery(g_objSlider).on(g_objSlider.events.ITEM_CHANGED, function(){
20472				 var sliderIndex = g_objSlider.getCurrentItemIndex();
20473				 				 
20474				 if(sliderIndex != -1)
20475					 t.selectItem(sliderIndex);
20476			 });
20477			 
20478			 //add slider onmousemove event
20479			 if(g_options.gallery_pause_on_mouseover == true){
20480				 var sliderElement = g_objSlider.getElement();
20481				 sliderElement.hover(onSliderMouseEnter, onSliderMouseLeave);
20482				 
20483				 //on full screen, run on mouse leave
20484				 g_objGallery.on(t.events.ENTER_FULLSCREEN, function(){
20485						 onSliderMouseLeave();
20486				 });
20487				 
20488			 }
20489			 
20490			 //retrigger slider events
20491			 retriggerEvent(g_objSlider, g_objSlider.events.ACTION_START, t.events.SLIDER_ACTION_START);
20492			 retriggerEvent(g_objSlider, g_objSlider.events.ACTION_END, t.events.SLIDER_ACTION_END);
20493			 
20494			 jQuery(g_objSlider).on(g_objSlider.events.CURRENTSLIDE_LOAD_END, onCurrentSlideImageLoadEnd);
20495		 
20496		 }
20497		  
20498		 //add keyboard events
20499		 if(g_options.gallery_control_keyboard == true)
20500			 jQuery(document).keydown(onKeyPress);
20501		 		 
20502	}
20503	
20504	
20505	/**
20506	 * destroy all gallery events
20507	 */
20508	this.destroy = function(){
20509		
20510		g_objWrapper.off("dragstart");
20511		g_objGallery.off(t.events.ITEM_IMAGE_UPDATED);
20512		
20513		//init custom event on strip moving
20514		if(g_objThumbs){
20515			switch(g_temp.thumbsType){
20516				case "strip":
20517					jQuery(g_objThumbs).off(g_objThumbs.events.STRIP_MOVE);
20518				break;
20519				case "grid":
20520					jQuery(g_objThumbs).off(g_objThumbs.events.PANE_CHANGE);
20521				break;
20522			}
20523		}
20524		
20525		 g_objWrapper.off("mousewheel");
20526		
20527		 jQuery(window).off("resize");
20528		 
20529		 //fullscreen:
20530		 g_functions.destroyFullScreenChangeEvent();
20531		 
20532		 //on slider item changed event
20533		 if(g_objSlider){
20534			 
20535			 jQuery(g_objSlider).off(g_objSlider.events.ITEM_CHANGED);
20536			 
20537			 //add slider onmousemove event
20538			 var sliderElement = g_objSlider.getElement();
20539			 sliderElement.off("mouseenter");
20540			 sliderElement.off("mouseleave");
20541			 
20542			 g_objGallery.off(t.events.ENTER_FULLSCREEN);
20543			 jQuery(g_objSlider).off(g_objSlider.events.ACTION_START);
20544			 jQuery(g_objSlider).off(g_objSlider.events.ACTION_END);
20545			 jQuery(g_objSlider).off(g_objSlider.events.CURRENTSLIDE_LOAD_END);
20546		 }
20547		 		 
20548		 //add keyboard events
20549		 if(g_options.gallery_control_keyboard == true)
20550			 jQuery(document).off("keydown");
20551		
20552		 //destroy theme
20553		 if(g_objTheme && typeof g_objTheme.destroy == "function"){
20554			 g_objTheme.destroy();
20555		 }
20556
20557		 g_objWrapper.html("");
20558	}
20559	
20560	
20561	function __________GENERAL_______(){};
20562	
20563	/**
20564	 * get items array
20565	 */
20566	this.getArrItems = function(){
20567		return g_arrItems;
20568	}
20569	
20570	/**
20571	 * get gallery objects
20572	 */
20573	this.getObjects = function(){
20574			
20575		var objects = {
20576			g_galleryID:g_galleryID,
20577			g_objWrapper:g_objWrapper,
20578			g_objThumbs:g_objThumbs,
20579			g_objSlider:g_objSlider,
20580			g_options:g_options,
20581			g_arrItems:g_arrItems,
20582			g_numItems:g_numItems
20583		};
20584		
20585		return(objects);
20586	}
20587	
20588	/**
20589	 * get slider object
20590	 */
20591	this.getObjSlider = function(){
20592		
20593		return(g_objSlider);
20594	}
20595	
20596	
20597	/**
20598	 * 
20599	 * get item by index, if the index don't fit, trace error
20600	 */
20601	this.getItem = function(index){
20602		if(index < 0){
20603			throw new Error("item with index: " + index + " not found");
20604			return(null);
20605		}
20606		if(index >= g_numItems){
20607			throw new Error("item with index: " + index + " not found");
20608			return(null);			
20609		}
20610		
20611		return(g_arrItems[index]);
20612	}
20613	
20614	
20615	/**
20616	 * get gallery width
20617	 */
20618	this.getWidth = function(){
20619		
20620		var objSize = t.getSize();
20621				
20622		return(objSize.width);
20623	}
20624	
20625	/**
20626	 * get gallery height
20627	 */
20628	this.getHeight = function(){
20629		
20630		var objSize = t.getSize();
20631		
20632		return(objSize.height);
20633	}
20634	
20635	
20636	/**
20637	 * get gallery size
20638	 */
20639	this.getSize = function(){
20640		
20641		var objSize = g_functions.getElementSize(g_objWrapper);
20642		
20643		objSize.orig_width = g_options.gallery_width;
20644		objSize.orig_height = g_options.gallery_height;
20645		objSize.orig_ratio = objSize.orig_width / objSize.orig_height;
20646		
20647		return(objSize);
20648	}
20649	
20650	/**
20651	 * get gallery ID
20652	 */
20653	this.getGalleryID = function(){
20654		
20655		var id = g_galleryID.replace("#","");
20656			
20657		return(id);
20658	}
20659	
20660	/**
20661	 * get next item by current index (or current object)
20662	 */
20663	this.getNextItem = function(index, forceCarousel){
20664		
20665		if(typeof index == "object")
20666			index = index.index;
20667		
20668		var nextIndex = index + 1;
20669		
20670		if(forceCarousel !== true && g_numItems == 1)
20671			return(null);
20672		
20673		if(nextIndex >= g_numItems){
20674			
20675			if(g_options.gallery_carousel == true || forceCarousel === true)
20676				nextIndex = 0;
20677			else
20678				return(null);
20679		}
20680		
20681		var objItem = g_arrItems[nextIndex];
20682		
20683		return(objItem);			
20684	}
20685	
20686	
20687	/**
20688	 * get previous item by index (or item object)
20689	 */
20690	this.getPrevItem = function(index){
20691		
20692		if(typeof index == "object")
20693			index = index.index;
20694		
20695		var prevIndex = index - 1;
20696		
20697		if(prevIndex < 0){
20698			if(g_options.gallery_carousel == true || forceCarousel === true)
20699				prevIndex = g_numItems - 1;
20700			else
20701				return(null);
20702		}
20703		
20704		var objItem = g_arrItems[prevIndex];
20705		
20706		return(objItem);
20707	}
20708	
20709	
20710	
20711	/**
20712	 * get selected item
20713	 */
20714	this.getSelectedItem = function(){
20715		
20716		return(g_selectedItem);
20717	}
20718	
20719	/**
20720	 * get selected item index
20721	 */
20722	this.getSelectedItemIndex = function(){
20723		
20724		return(g_selectedItemIndex);
20725	}
20726	
20727	
20728	/**
20729	 * get number of items
20730	 */
20731	this.getNumItems = function(){
20732		return g_numItems;
20733	}
20734	
20735	/**
20736	 * get true if the current item is last
20737	 */
20738	this.isLastItem = function(){
20739		if(g_selectedItemIndex == g_numItems - 1)
20740			return(true);
20741		
20742		return(false);
20743	}
20744	
20745	
20746	/**
20747	 * get true if the current item is first
20748	 */
20749	this.isFirstItem = function(){
20750		if(g_selectedItemIndex == 0)
20751			return(true);
20752		return(false);
20753	}
20754	
20755	
20756	/**
20757	 * get gallery options
20758	 */
20759	this.getOptions = function(){
20760		return g_options;
20761	}
20762	
20763	
20764	/**
20765	 * get the gallery wrapper element
20766	 */
20767	this.getElement = function(){
20768		return(g_objWrapper);
20769	}
20770	
20771	
20772	this.___________SET_CONTROLS___________ = function(){}
20773	
20774	/**
20775	 * set next button element
20776	 * set onclick event
20777	 */
20778	this.setNextButton = function(objButton){
20779		
20780		//register button as a unite gallery belong
20781		objButton.data("ug-button", true);
20782		
20783		g_functions.setButtonOnClick(objButton, t.nextItem);
20784		
20785	}
20786	
20787	
20788	/**
20789	 * set prev button element
20790	 * set onclick event
20791	 */
20792	this.setPrevButton = function(objButton){
20793		
20794		//register button as a unite gallery belong
20795		objButton.data("ug-button", true);
20796		
20797		g_functions.setButtonOnClick(objButton, t.prevItem);
20798				
20799	}
20800	
20801	
20802	/**
20803	 * set fullscreen button to enter / exit fullscreen.
20804	 * on fullscreen mode ug-fullscreenmode class wil be added
20805	 */
20806	this.setFullScreenToggleButton = function(objButton){
20807		
20808		//register button as a unite gallery belong
20809		objButton.data("ug-button", true);
20810
20811		g_functions.setButtonOnClick(objButton, t.toggleFullscreen);
20812		
20813		g_objGallery.on(t.events.ENTER_FULLSCREEN,function(){
20814			objButton.addClass("ug-fullscreenmode");
20815		});
20816		
20817		g_objGallery.on(t.events.EXIT_FULLSCREEN,function(){
20818			objButton.removeClass("ug-fullscreenmode");
20819		});
20820				
20821	}
20822	
20823	
20824	/**
20825	 * destroy full screen button
20826	 */
20827	this.destroyFullscreenButton = function(objButton){
20828		
20829		g_functions.destroyButton(objButton);
20830		
20831		g_objGallery.off(t.events.ENTER_FULLSCREEN);
20832		g_objGallery.off(t.events.EXIT_FULLSCREEN);
20833	}
20834	
20835	
20836	/**
20837	 * set play button event
20838	 */
20839	this.setPlayButton = function(objButton){
20840		
20841		//register button as a unite gallery belong
20842		objButton.data("ug-button", true);
20843		
20844		g_functions.setButtonOnClick(objButton, t.togglePlayMode);
20845		
20846		g_objGallery.on(t.events.START_PLAY,function(){
20847			objButton.addClass("ug-stop-mode");
20848		});
20849		
20850		g_objGallery.on(t.events.STOP_PLAY, function(){
20851			objButton.removeClass("ug-stop-mode");
20852		});
20853		
20854	}
20855	
20856	/**
20857	 * destroy the play button
20858	 */
20859	this.destroyPlayButton = function(objButton){
20860		g_functions.destroyButton(objButton);
20861		g_objGallery.off(t.events.START_PLAY);
20862		g_objGallery.off(t.events.STOP_PLAY);
20863	}
20864	
20865	/**
20866	 * set playing progress indicator
20867	 */
20868	this.setProgressIndicator = function(objProgress){
20869		
20870		g_temp.objProgress = objProgress;		
20871	}
20872	
20873	
20874	/**
20875	 * set title and descreiption containers
20876	 */
20877	this.setTextContainers = function(objTitle, objDescription){
20878		
20879		g_objGallery.on(t.events.ITEM_CHANGE, function(){
20880			
20881			var objItem = t.getSelectedItem();			
20882			objTitle.html(objItem.title);
20883			objDescription.html(objItem.description);
20884			
20885		});
20886		
20887	}
20888	
20889	/**
20890	 * show overlay disabled
20891	 */
20892	this.showDisabledOverlay = function(){
20893		g_objWrapper.children(".ug-overlay-disabled").show();
20894	}
20895
20896	/**
20897	 * show overlay disabled
20898	 */
20899	this.hideDisabledOverlay = function(){
20900		g_objWrapper.children(".ug-overlay-disabled").hide();
20901	}
20902	
20903	this.___________END_SET_CONTROLS___________ = function(){}
20904
20905	
20906	/**
20907	 * cache items, put to cache array by id
20908	 * the items must be unprocessed yet
20909	 */
20910	function cacheItems(cacheID, htmlItemsArg){
20911			
20912		if(htmlItemsArg){
20913			var htmlItems = htmlItemsArg;
20914			if(htmlItems != "noitems")
20915				htmlItems = jQuery(htmlItemsArg).clone();
20916		}else{
20917			var htmlItems = g_objWrapper.children().clone();
20918		}
20919		
20920		g_objCache[cacheID] = htmlItems;
20921	}
20922	
20923	
20924	/**
20925	 * remove all size classes
20926	 */
20927	function removeAllSizeClasses(objWrapper){
20928		
20929		if(!objWrapper)
20930			objWrapper = g_objWrapper;
20931		
20932		objWrapper.removeClass("ug-under-480");
20933		objWrapper.removeClass("ug-under-780");
20934		objWrapper.removeClass("ug-under-960");
20935	}
20936	
20937	
20938	
20939	
20940	/**
20941	 * retrigger event from another objects
20942	 * the second parameter will be the second object
20943	 */
20944	function retriggerEvent(object, originalEvent, newEvent){
20945		
20946		jQuery(object).on(originalEvent, function(event){
20947			g_objGallery.trigger(newEvent, [this]);
20948		});
20949	
20950	}
20951	
20952	
20953	/**
20954	 * advance next play step
20955	 */
20956	function advanceNextStep(){
20957				
20958		var timeNow = jQuery.now();
20959		var timeDiff = timeNow - g_temp.playTimeLastStep;
20960		g_temp.playTimePassed += timeDiff;
20961		g_temp.playTimeLastStep = timeNow;
20962		
20963		//set the progress
20964		if(g_temp.objProgress){
20965			var percent = g_temp.playTimePassed / g_options.gallery_play_interval;
20966			g_temp.objProgress.setProgress(percent);
20967		}
20968		
20969		//if interval passed - proceed to next item
20970		if(g_temp.playTimePassed >= g_options.gallery_play_interval){
20971			
20972			t.nextItem();
20973			g_temp.playTimePassed = 0;			
20974		}
20975		
20976		
20977	}
20978	
20979	this.___________PLAY_MODE___________ = function(){}
20980	
20981	
20982	/**
20983	 * start play mode
20984	 */
20985	this.startPlayMode = function(){
20986		
20987		g_temp.isPlayMode = true;
20988		g_temp.isPlayModePaused = false;
20989		
20990		g_temp.playTimePassed = 0;
20991		g_temp.playTimeLastStep = jQuery.now();
20992		
20993		g_temp.playHandle = setInterval(advanceNextStep, g_temp.playStepInterval);
20994		
20995		//show and reset progress indicator
20996		if(g_temp.objProgress){
20997			var objElement = g_temp.objProgress.getElement();
20998			g_temp.objProgress.setProgress(0);
20999			objElement.show();
21000		}
21001		
21002		g_objGallery.trigger(t.events.START_PLAY);
21003		
21004		//check if there is a need to pause
21005		if(g_objSlider && g_objSlider.isCurrentSlideLoadingImage() == true){
21006			t.pausePlaying();
21007		}
21008		
21009	}
21010	
21011	
21012	/**
21013	 * reset playing - set the timer to 0
21014	 */
21015	this.resetPlaying = function(){
21016		
21017		if(g_temp.isPlayMode == false)
21018			return(true);
21019		
21020		g_temp.playTimePassed = 0;
21021		g_temp.playTimeLastStep = jQuery.now();
21022	}
21023	
21024	
21025	/**
21026	 * pause playing slideshow
21027	 */
21028	this.pausePlaying = function(){
21029		
21030		if(g_temp.isPlayModePaused == true)
21031			return(true);
21032		
21033		g_temp.isPlayModePaused = true;
21034		clearInterval(g_temp.playHandle);
21035		
21036		g_objGallery.trigger(t.events.PAUSE_PLAYING);
21037	}
21038	
21039	
21040	/**
21041	 * continue playing slideshow
21042	 */
21043	this.continuePlaying = function(){
21044		
21045		if(g_temp.isPlayModePaused == false)
21046			return(true);
21047		
21048		g_temp.isPlayModePaused = false;
21049		g_temp.playTimeLastStep = jQuery.now();
21050		g_temp.playHandle = setInterval(advanceNextStep, g_temp.playStepInterval);
21051		
21052	}
21053	
21054	
21055	/**
21056	 * stop play mode
21057	 */
21058	this.stopPlayMode = function(){
21059		g_temp.isPlayMode = false;
21060		clearInterval(g_temp.playHandle);
21061			
21062		g_temp.playTimePassed = 0;
21063		
21064		//hide progress indicator
21065		if(g_temp.objProgress){
21066			var objElement = g_temp.objProgress.getElement();
21067			objElement.hide();
21068		}
21069		
21070		g_objGallery.trigger(t.events.STOP_PLAY);
21071	}
21072	
21073	
21074	/**
21075	 * tells if the play mode are active
21076	 */
21077	this.isPlayMode = function(){
21078		
21079		return(g_temp.isPlayMode);
21080	}
21081	
21082	
21083	/**
21084	 * start / stop play mode
21085	 */
21086	this.togglePlayMode = function(){
21087		
21088		if(t.isPlayMode() == false)
21089			t.startPlayMode();
21090		else
21091			t.stopPlayMode();
21092	}
21093
21094	
21095	/**
21096	 * unselect all items
21097	 */
21098	function unselectSeletedItem(){
21099		
21100		if(g_selectedItem == null)
21101			return(true);
21102		
21103		if(g_objThumbs)
21104			g_objThumbs.setThumbUnselected(g_selectedItem.objThumbWrapper);
21105		
21106		g_selectedItem = null;
21107		g_selectedItemIndex = -1;
21108	}	
21109	
21110	
21111	this.___________GENERAL_EXTERNAL___________ = function(){}
21112	
21113	/**
21114	 * shuffle items - usually before theme start
21115	 */
21116	this.shuffleItems = function(){
21117
21118		g_arrItems = g_functions.arrayShuffle(g_arrItems);
21119		
21120		for(var index in g_arrItems)		//fix index
21121			g_arrItems[index].index = parseInt(index);
21122		
21123	}
21124	
21125	/**
21126	 * set main gallery params, extend current params
21127	 */
21128	this.setOptions = function(customOptions){
21129				
21130		g_options = jQuery.extend(g_options, customOptions);		
21131	}
21132	
21133	
21134	/**
21135	 * select some item
21136	 * the input can be index or object
21137	 * role - the role of the object who selected the item
21138	 */
21139	this.selectItem = function(objItem, role){
21140		
21141		if(typeof objItem == "number")
21142			objItem = t.getItem(objItem);
21143		
21144		var itemIndex = objItem.index;
21145		if(itemIndex == g_selectedItemIndex)
21146			return(true);
21147				
21148		unselectSeletedItem();
21149				
21150		//set selected item
21151		g_selectedItem = objItem;		
21152		g_selectedItemIndex = itemIndex;
21153		
21154		g_objGallery.trigger(t.events.ITEM_CHANGE, [objItem,role]);
21155		
21156		//reset playback, if playing
21157		if(g_temp.isPlayMode == true){
21158				t.resetPlaying();
21159			
21160			var stillLoading = g_objSlider.isCurrentSlideLoadingImage();
21161			if(stillLoading == true)
21162				t.pausePlaying();
21163		}
21164				
21165	}
21166	
21167	
21168	/**
21169	 * go to next item
21170	 */
21171	this.nextItem = function(){
21172		
21173		var newItemIndex = g_selectedItemIndex + 1;
21174		
21175		if(g_numItems == 0)
21176			return(true);		
21177		
21178		if(g_options.gallery_carousel == false && newItemIndex >= g_numItems)
21179			return(true);
21180		
21181		if(newItemIndex >= g_numItems)
21182			newItemIndex = 0;
21183		
21184		//debugLine(newItemIndex,true);
21185		
21186		t.selectItem(newItemIndex, "next");
21187	}
21188	
21189	
21190	/**
21191	 * go to previous item
21192	 */
21193	this.prevItem = function(){
21194		
21195		var newItemIndex = g_selectedItemIndex - 1;
21196		
21197		if(g_selectedItemIndex == -1)
21198			newItemIndex = 0;
21199		
21200		if(g_numItems == 0)
21201			return(true);
21202		
21203		if(g_options.gallery_carousel == false && newItemIndex < 0)
21204			return(true);
21205		
21206		if(newItemIndex < 0)
21207			newItemIndex = g_numItems - 1;
21208		
21209		t.selectItem(newItemIndex, "prev");
21210		
21211	}
21212	
21213	
21214	/**
21215	 * expand gallery to body size
21216	 */
21217	function toFakeFullScreen(){
21218		
21219		jQuery("body").addClass("ug-body-fullscreen");
21220		g_objWrapper.addClass("ug-fake-fullscreen");
21221		
21222		g_temp.isFakeFullscreen = true;
21223		
21224		g_objGallery.trigger(t.events.ENTER_FULLSCREEN);
21225		g_objGallery.trigger(t.events.SIZE_CHANGE);
21226	}
21227	
21228	
21229	/**
21230	 * exit fake fullscreen
21231	 */
21232	function exitFakeFullscreen(){
21233		
21234		jQuery("body").removeClass("ug-body-fullscreen");
21235		g_objWrapper.removeClass("ug-fake-fullscreen");
21236		
21237		g_temp.isFakeFullscreen = false;
21238		
21239		g_objGallery.trigger(t.events.EXIT_FULLSCREEN);
21240		g_objGallery.trigger(t.events.SIZE_CHANGE);
21241		
21242	}
21243	
21244	/**
21245	 * return if the fullscreen mode is available
21246	 */
21247	this.isFullScreen = function(){
21248		
21249		if(g_temp.isFakeFullscreen == true)
21250			return(true);
21251		
21252		if(g_functions.isFullScreen() == true)
21253			return(true);
21254		
21255		return(false);		
21256	}
21257	
21258	
21259	/**
21260	 * tells if it's fake fullscreen
21261	 */
21262	this.isFakeFullscreen = function(){
21263		
21264		return(g_temp.isFakeFullscreen);
21265	}
21266	
21267	
21268	/**
21269	 * go to fullscreen mode
21270	 */
21271	this.toFullScreen = function(){
21272		
21273		g_functions.setGlobalData("fullscreenID", g_galleryID);
21274		
21275		var divGallery = g_objWrapper.get(0);
21276		
21277		var isSupported = g_functions.toFullscreen(divGallery);
21278				
21279		if(isSupported == false)
21280			toFakeFullScreen();
21281		
21282	}
21283	
21284	
21285	/**
21286	 * exit full screen
21287	 */
21288	this.exitFullScreen = function(){
21289		
21290		if(g_temp.isFakeFullscreen == true)
21291			exitFakeFullscreen();
21292		else
21293			g_functions.exitFullscreen();
21294						
21295	}
21296	
21297	/**
21298	 * toggle fullscreen
21299	 */
21300	this.toggleFullscreen = function(){
21301		
21302		if(t.isFullScreen() == false){
21303			t.toFullScreen();
21304		}else{
21305			t.exitFullScreen();
21306		}
21307		
21308	}
21309	
21310	/**
21311	 * resize the gallery
21312	 * noevent - initally false
21313	 */
21314	this.resize = function(newWidth, newHeight, noevent){
21315		
21316		g_objWrapper.css("width", "auto");
21317		g_objWrapper.css("max-width",newWidth+"px");
21318		
21319		if(newHeight)
21320			g_objWrapper.height(newHeight);
21321		
21322		if(!noevent && noevent !== true)
21323			onGalleryResized();
21324		
21325	}
21326
21327	
21328	/**
21329	 * set size class to the wrapper
21330	 * this can work to any other wrapper too
21331	 */
21332	this.setSizeClass = function(objWrapper, width){
21333		
21334		if(!objWrapper)
21335			var objWrapper = g_objWrapper;
21336		
21337		if(!width){
21338			var objSize = t.getSize();
21339			var width = objSize.width;			
21340		}
21341		
21342		if(width == 0)
21343			var width = jQuery(window).width();
21344		
21345		var addClass = "";
21346		
21347		if(width <= 480){
21348			addClass = "ug-under-480";			
21349		}else
21350		if(width <= 780){
21351			addClass = "ug-under-780";			
21352		}else
21353		if(width < 960){
21354			addClass = "ug-under-960";
21355		}
21356		
21357		if(objWrapper.hasClass(addClass) == true)
21358			return(true);
21359		
21360		removeAllSizeClasses(objWrapper);
21361		if(addClass != "")
21362			objWrapper.addClass(addClass);
21363	}
21364	
21365	
21366	/**
21367	 * return if the size is suited for mobile
21368	 */
21369	this.isMobileMode = function(){
21370		
21371		if(g_objWrapper.hasClass("ug-under-480"))
21372			return(true);
21373		
21374		return(false);
21375	}
21376	
21377	
21378	/**
21379	 * get if small screen
21380	 */
21381	this.isSmallWindow = function(){
21382		
21383		var windowWidth = jQuery(window).width();
21384		
21385		
21386		if(!windowWidth)
21387			return(true);
21388		
21389		if(windowWidth <= 480)
21390			return(true);
21391		
21392		return(false);
21393	}
21394	
21395	
21396	/**
21397	 * change gallery items
21398	 */
21399	this.changeItems = function(itemsContent, cacheID){
21400		
21401		if(!itemsContent)
21402			var itemsContent = "noitems";
21403		
21404		runGallery(g_galleryID, "nochange", itemsContent, cacheID);
21405	}
21406	
21407	/**
21408	 * show error message, replace whole gallery div
21409	 */
21410	this.showErrorMessageReplaceGallery = function(message){
21411		showErrorMessage(message);
21412	}
21413	
21414	/**
21415	 * set custom height function by width
21416	 */
21417	this.setFuncCustomHeight = function(func){
21418		g_temp.funcCustomHeight = func;
21419	}
21420	
21421	this.__________AJAX_REQUEST_______ = function(){};
21422	
21423	
21424	/**
21425	 * ajax request
21426	 */
21427	this.ajaxRequest = function(action, data, isJSON, successFunction){
21428		
21429		var dataType = "html";
21430		if(isJSON == true)
21431			dataType = "json";
21432				
21433		if(!successFunction || typeof successFunction != "function")
21434			throw new Error("ajaxRequest error: success function should be passed");
21435
21436		var urlAjax = g_options.gallery_urlajax;
21437		if(urlAjax == "")
21438			throw new Error("ajaxRequest error: Ajax url don't passed");
21439		
21440		if(typeof data == "undefined")
21441			var data = {};
21442
21443		//add galleryID to data
21444		var objData = {
21445				action:"unitegallery_ajax_action",
21446				client_action:action,
21447				galleryID: g_galleryID,
21448				data:data
21449		};
21450		
21451		jQuery.ajax({
21452			type:"post",
21453			url:g_options.gallery_urlajax,
21454			dataType: 'json',
21455			data:objData,
21456			success:function(response){
21457				
21458				if(!response){
21459					showErrorMessage("Empty ajax response!", "Ajax Error");
21460					return(false);					
21461				}
21462
21463				if(response == -1 || response === 0){
21464					showErrorMessage("ajax error!!!");
21465					return(false);
21466				}
21467
21468				if(typeof response.success == "undefined"){
21469					showErrorMessage("The 'success' param is a must!");
21470					return(false);
21471				}
21472				
21473				if(response.success == false){
21474					showErrorMessage(response.message);
21475					return(false);
21476				}
21477				
21478				successFunction(response);
21479			},		 	
21480			error:function(jqXHR, textStatus, errorThrown){
21481				console.log("Ajax Error!!! " + textStatus);
21482			}
21483		});
21484		
21485	}
21486	
21487	
21488	/**
21489	 * request new items
21490	 * isForce - don't take from cache
21491	 */
21492	this.requestNewItems = function(catID, isForce, cacheID){
21493		
21494		var checkCache = g_options.gallery_enable_cache;
21495		
21496		if(!cacheID)
21497			cacheID = catID;
21498		
21499		if(isForce == true)
21500			checkCache = false;
21501		
21502		//get items from cache
21503		if(checkCache == true && g_objCache.hasOwnProperty(cacheID)){
21504			
21505			var htmlItems = g_objCache[cacheID];
21506			
21507			t.changeItems(htmlItems, cacheID);
21508			
21509		}else{
21510			
21511			g_objGallery.trigger(t.events.GALLERY_BEFORE_REQUEST_ITEMS);
21512			
21513			t.ajaxRequest("front_get_cat_items",{catid:catID}, true, function(response){
21514				
21515				var htmlItems = response.html;
21516								
21517				t.changeItems(htmlItems, cacheID);
21518				
21519			});
21520			
21521		}
21522		
21523	}
21524	
21525	
21526	/**
21527	 * run the gallery
21528	 */
21529	 this.run = function(galleryID, objParams){
21530		 
21531		 
21532		 var debug_errors = g_options.gallery_debug_errors;
21533		 if(objParams && objParams.hasOwnProperty("gallery_debug_errors"))
21534			 g_options.gallery_debug_errors = objParams.gallery_debug_errors;
21535
21536		 
21537		 if(g_options.gallery_debug_errors == true){
21538			 
21539			 try{
21540				 
21541				 runGallery(galleryID, objParams);
21542				 
21543				 
21544			 }catch(objError){
21545				 if(typeof objError == "object"){
21546					 
21547					 var message = objError.message;
21548					 var lineNumber = objError.lineNumber;
21549					 var fileName = objError.fileName;
21550					 var stack = objError.stack;
21551					 
21552					 message += " <br><br> in file: "+fileName;
21553					 message += " <b> line " + lineNumber + "</b>";
21554					 
21555					 trace(objError);
21556					 
21557				 }else{
21558					 var message = objError;
21559				 }
21560				 
21561				 //remove double "error:" text
21562				 message = message.replace("Error:","");
21563				 
21564				 showErrorMessage(message);
21565			 }
21566			 
21567		 }else{
21568			 runGallery(galleryID, objParams);
21569		 }
21570		 
21571		 		 
21572		 
21573	 }
21574	 	 	 
21575}	//unitegallery object end
21576
21577
21578/**
21579 * tiles class
21580 */
21581function UGLightbox(){
21582
21583	var t = this, g_objThis = jQuery(this);
21584	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objWrapper;
21585	var g_objSlider = new UGSlider(), g_objOverlay, g_objArrowLeft, g_objArrowRight, g_objButtonClose;
21586	var g_functions = new UGFunctions(), g_objTextPanel = new UGTextPanel(), g_objNumbers;
21587	var g_objTopPanel;
21588	
21589	var g_options = {
21590			lightbox_type: "wide",							//compact / wide - lightbox type
21591			
21592			lightbox_show_textpanel: true,					//show the text panel
21593			lightbox_textpanel_width: 550,					//the width of the text panel.
21594			
21595			lightbox_hide_arrows_onvideoplay: true,			//hide the arrows when video start playing and show when stop
21596			lightbox_arrows_position: "sides",				//sides, inside: position of the arrows, used on compact type			
21597			lightbox_arrows_offset: 10,						//The horizontal offset of the arrows
21598			lightbox_arrows_inside_offset: 10,				//The offset from the image border if the arrows placed inside
21599			lightbox_arrows_inside_alwayson: false,			//Show the arrows on mouseover, or always on.
21600			
21601			lightbox_overlay_color:null,					//the color of the overlay. if null - will take from css
21602			lightbox_overlay_opacity:1,						//the opacity of the overlay. if null - will take from css
21603			lightbox_top_panel_opacity: null,				//the opacity of the top panel
21604			
21605			lightbox_show_numbers: true,					//show numbers on the right side
21606			lightbox_numbers_size: null,					//the size of the numbers string
21607			lightbox_numbers_color: null,					//the color of the numbers
21608			lightbox_numbers_padding_top:null,				//the top padding of the numbers (used in compact mode)
21609			lightbox_numbers_padding_right:null,			//the right padding of the numbers (used in compact mode)
21610			
21611			lightbox_compact_closebutton_offsetx: 1,		//the offsetx of the close button. Valid only for compact mode
21612			lightbox_compact_closebutton_offsety: 1,		//the offsetx of the close button. Valid only for compact mode
21613			
21614			lightbox_close_on_emptyspace:true				//close the lightbox on empty space
21615	};
21616	
21617	this.events = {
21618			LIGHTBOX_INIT: "lightbox_init"
21619	};
21620	
21621	var g_temp = {
21622			topPanelHeight: 44,
21623			initTextPanelHeight: 26,		//init height for compact mode
21624			isOpened: false, 
21625			isRightNowOpened:false,
21626			putSlider: true,
21627			isCompact: false,
21628			fadeDuration: 300,
21629			positionFrom: null,
21630			textPanelTop: null,
21631			textPanelLeft: null,
21632			isArrowsInside: false,
21633			isArrowsOnHoverMode: false,
21634			lastMouseX: null,
21635			lastMouseY: null,
21636			originalOptions: null,
21637			isSliderChangedOnce:false,
21638			isTopPanelEnabled:true
21639	};
21640	
21641	var g_defaults = {
21642			lightbox_slider_controls_always_on: true,
21643			lightbox_slider_enable_bullets: false,
21644			lightbox_slider_enable_arrows: false,
21645			lightbox_slider_enable_progress_indicator: false,
21646			lightbox_slider_enable_play_button: false,
21647			lightbox_slider_enable_fullscreen_button: false,
21648			lightbox_slider_enable_zoom_panel: false,
21649			lightbox_slider_enable_text_panel: false,
21650			lightbox_slider_scale_mode_media: "down",
21651			lightbox_slider_scale_mode: "down",
21652			lightbox_slider_loader_type: 3,
21653			lightbox_slider_loader_color: "black",
21654			lightbox_slider_transition: "fade",
21655			
21656			lightbox_slider_image_padding_top: g_temp.topPanelHeight,
21657			lightbox_slider_image_padding_bottom: 0,
21658			
21659			lightbox_slider_video_padding_top: 0,
21660			lightbox_slider_video_padding_bottom: 0,
21661			
21662			lightbox_textpanel_align: "middle",
21663			lightbox_textpanel_padding_top: 5,
21664			lightbox_textpanel_padding_bottom: 5,
21665			
21666			slider_video_constantsize: false,
21667			lightbox_slider_image_border: false,
21668			
21669			lightbox_textpanel_enable_title: true,
21670			lightbox_textpanel_enable_description: false,
21671			lightbox_textpanel_desc_style_as_title: true,
21672			
21673			lightbox_textpanel_enable_bg:false,
21674			
21675			video_enable_closebutton: false,
21676			lightbox_slider_video_enable_closebutton: false,
21677			video_youtube_showinfo: false,
21678			lightbox_slider_enable_links:false
21679	};
21680	
21681	var g_defaultsCompact = {
21682			lightbox_overlay_opacity:0.6,
21683			
21684			lightbox_slider_image_border: true,
21685			lightbox_slider_image_shadow:true,
21686			lightbox_slider_image_padding_top: 30,
21687			lightbox_slider_image_padding_bottom: 30,
21688			
21689			slider_video_constantsize: true,
21690						
21691			lightbox_textpanel_align: "bottom",
21692			lightbox_textpanel_title_text_align: "left",
21693			lightbox_textpanel_desc_text_align: "left",
21694			lightbox_textpanel_padding_left: 10,			//the padding left of the textpanel
21695			lightbox_textpanel_padding_right: 10
21696	};
21697	
21698	
21699	function __________GENERAL_________(){};
21700	
21701	
21702	/**
21703	 * init the gallery
21704	 */
21705	function initLightbox(gallery, customOptions){
21706		
21707		g_gallery = gallery;
21708		g_objGallery = jQuery(gallery);
21709		
21710		g_options = jQuery.extend(g_options, g_defaults);
21711		g_options = jQuery.extend(g_options, customOptions);
21712		
21713		g_temp.originalOptions = jQuery.extend({}, g_options);
21714		
21715		if(g_options.lightbox_type == "compact"){
21716			g_temp.isCompact = true;
21717			g_options = jQuery.extend(g_options, g_defaultsCompact);
21718			g_options = jQuery.extend(g_options, customOptions);
21719		}
21720		
21721		//modify some options
21722		modifyOptions();
21723		
21724		if(g_temp.putSlider == true){
21725			
21726			g_gallery.initSlider(g_options, "lightbox");
21727			g_objects = gallery.getObjects();
21728			g_objSlider = g_objects.g_objSlider;			
21729			
21730		}else{
21731			g_objSlider = null;
21732		}
21733		
21734		if(g_options.lightbox_show_textpanel == true){
21735			g_objTextPanel.init(g_gallery, g_options, "lightbox");
21736		}
21737		else
21738			g_objTextPanel = null;
21739		
21740		
21741	}
21742	
21743	
21744	/**
21745	 * modify some options according user options
21746	 */
21747	function modifyOptions(){
21748		
21749		if(g_temp.isCompact == true && g_options.lightbox_show_textpanel == true){
21750			g_options.lightbox_slider_image_padding_bottom = g_temp.initTextPanelHeight;
21751		}
21752		
21753		if(g_temp.isCompact == true && g_options.lightbox_arrows_position == "inside"){
21754			g_temp.isArrowsInside = true;
21755		}
21756
21757		if(g_temp.isArrowsInside == true && g_options.lightbox_arrows_inside_alwayson == false)
21758			g_temp.isArrowsOnHoverMode = true;
21759		
21760		//disable top panel if no text panel enabled
21761		if(g_options.lightbox_show_textpanel == false){
21762			g_temp.isTopPanelEnabled = false;
21763			g_temp.topPanelHeight = 0;
21764			g_options.lightbox_slider_image_padding_top = 0;
21765		}
21766		
21767		//modify slider image border width
21768		
21769		
21770	}
21771	
21772	
21773	/**
21774	 * put the lightbox html
21775	 */
21776	function putLightboxHtml(){
21777		
21778		var html = "";
21779		var classAddition = "";
21780		if(g_temp.isCompact == true){
21781			classAddition = " ug-lightbox-compact";
21782		}
21783		
21784		html += "<div class='ug-gallery-wrapper ug-lightbox"+classAddition+"'>";
21785		html += "<div class='ug-lightbox-overlay'></div>";
21786		
21787		//set top panel only on wide mode
21788		if(g_temp.isCompact == false && g_temp.isTopPanelEnabled){
21789			html += "<div class='ug-lightbox-top-panel'>";
21790			html += 	"<div class='ug-lightbox-top-panel-overlay'></div>";
21791			
21792			if(g_options.lightbox_show_numbers)
21793				html += 	"<div class='ug-lightbox-numbers'></div>";
21794			
21795			html += "</div>";	//top panel
21796		}else{
21797			
21798			//put numbers without top panel
21799			if(g_options.lightbox_show_numbers)
21800				html += 	"<div class='ug-lightbox-numbers'></div>";
21801			
21802		}
21803		
21804		
21805		html += 	"<div class='ug-lightbox-button-close'></div>";
21806		
21807		html += "<div class='ug-lightbox-arrow-left'></div>";		
21808		html += "<div class='ug-lightbox-arrow-right'></div>";
21809		
21810		html += "</div>";
21811		
21812		g_objWrapper = jQuery(html);
21813		
21814		jQuery("body").append(g_objWrapper);
21815		
21816		if(g_objSlider)
21817			g_objSlider.setHtml(g_objWrapper);
21818		
21819		g_objOverlay = g_objWrapper.children(".ug-lightbox-overlay");
21820		
21821		if(g_temp.isCompact == false && g_temp.isTopPanelEnabled == true){
21822			g_objTopPanel = g_objWrapper.children(".ug-lightbox-top-panel");
21823			if(g_objTopPanel.length == 0)
21824				g_objTopPanel = null;
21825		}
21826		
21827		g_objButtonClose = g_objWrapper.find(".ug-lightbox-button-close");
21828		
21829		if(g_options.lightbox_show_numbers)
21830			g_objNumbers = g_objWrapper.find(".ug-lightbox-numbers");
21831		
21832		g_objArrowLeft = g_objWrapper.children(".ug-lightbox-arrow-left");
21833		g_objArrowRight = g_objWrapper.children(".ug-lightbox-arrow-right");
21834				
21835		if(g_objTextPanel){
21836			if(g_objTopPanel)
21837				g_objTextPanel.appendHTML(g_objTopPanel);
21838			else
21839				g_objTextPanel.appendHTML(g_objWrapper);
21840		}
21841
21842	}
21843	
21844	
21845	/**
21846	 * set lightbox properties
21847	 */
21848	function setProperties(){
21849		
21850		if(g_options.lightbox_overlay_color !== null)
21851			g_objOverlay.css("background-color", g_options.lightbox_overlay_color);
21852		
21853		if(g_options.lightbox_overlay_opacity !== null)
21854			g_objOverlay.fadeTo(0, g_options.lightbox_overlay_opacity);
21855		
21856		if(g_objTopPanel && g_options.lightbox_top_panel_opacity !== null){
21857			g_objTopPanel.children(".ug-lightbox-top-panel-overlay").fadeTo(0, g_options.lightbox_top_panel_opacity);
21858		}
21859			
21860		//set numbers properties
21861		if(g_objNumbers){
21862			var cssNumbers = {};
21863			
21864			if(g_options.lightbox_numbers_size !== null)
21865				cssNumbers["font-size"] = g_options.lightbox_numbers_size+"px";
21866			
21867			if(g_options.lightbox_numbers_color)
21868				cssNumbers["color"] = g_options.lightbox_numbers_color;
21869			
21870			if(g_options.lightbox_numbers_padding_right !== null)
21871				cssNumbers["padding-right"] = g_options.lightbox_numbers_padding_right + "px";
21872			
21873			if(g_options.lightbox_numbers_padding_top !== null)
21874				cssNumbers["padding-top"] = g_options.lightbox_numbers_padding_top + "px";
21875			
21876			
21877			g_objNumbers.css(cssNumbers);
21878		}
21879		
21880	}
21881	
21882	
21883	/**
21884	 * refresh slider item with new height
21885	 */
21886	function refreshSliderItem(newHeight){
21887		
21888		if(!g_objSlider)
21889			return(true);
21890				
21891		//set slider new image position
21892		var objOptions = {
21893				slider_image_padding_top: newHeight
21894		};
21895		
21896		g_objSlider.setOptions(objOptions);
21897		g_objSlider.refreshSlideItems();
21898	
21899	}
21900	
21901	function __________WIDE_ONLY_________(){};
21902	
21903	
21904	/**
21905	 * handle panel height according text height
21906	 */
21907	function handlePanelHeight(fromWhere){
21908		
21909		if(!g_objTopPanel)
21910			return(false);
21911			
21912		if(!g_objTextPanel)
21913			return(false);
21914		
21915		//check text panel size, get the panel bigger then
21916		var panelHeight = g_objTopPanel.height();
21917		if(panelHeight == 0)
21918			return(false);
21919		
21920		if(g_objTopPanel.is(":visible") == false)
21921			return(false);
21922		
21923		var newPanelHeight = panelHeight;
21924		
21925		var objTextPanelSize = g_objTextPanel.getSize();
21926		
21927		var textPanelHeight = objTextPanelSize.height;
21928		
21929		if(panelHeight != g_temp.topPanelHeight)
21930			newPanelHeight = g_temp.topPanelHeight;
21931				
21932		if(textPanelHeight > newPanelHeight)
21933			newPanelHeight = textPanelHeight;
21934				
21935		if(panelHeight != newPanelHeight){
21936			g_objTopPanel.height(newPanelHeight);
21937			
21938			if(g_objSlider && g_objSlider.isAnimating() == false)
21939				refreshSliderItem(newPanelHeight);
21940		}
21941				
21942	}
21943
21944
21945	/**
21946	 * position text panel for wide
21947	 * size - wrapper size
21948	 */
21949	function positionTextPanelWide(size){
21950
21951		var objOptions = {};
21952		
21953		var textWidth = g_options.lightbox_textpanel_width;
21954		var minPaddingLeft = 47;
21955		var minPaddingRight = 40;
21956		var maxTextPanelWidth = size.width - minPaddingLeft - minPaddingRight;
21957		
21958		if(textWidth > maxTextPanelWidth){		//mobile mode
21959			
21960			objOptions.textpanel_padding_left = minPaddingLeft;
21961			objOptions.textpanel_padding_right = minPaddingRight;
21962			
21963			objOptions.textpanel_title_text_align = "center";
21964			objOptions.textpanel_desc_text_align = "center";			
21965		}else{
21966			objOptions.textpanel_padding_left = Math.floor((size.width - textWidth) / 2);
21967			objOptions.textpanel_padding_right = objOptions.textpanel_padding_left;
21968			objOptions.textpanel_title_text_align = "left";
21969			objOptions.textpanel_desc_text_align = "left";
21970			
21971			if(g_options.lightbox_textpanel_title_text_align)
21972					objOptions.textpanel_title_text_align = g_options.lightbox_textpanel_desc_text_align;
21973			
21974			if(g_options.lightbox_textpanel_desc_text_align)
21975				objOptions.textpanel_desc_text_align = g_options.lightbox_textpanel_desc_text_align;
21976			
21977		}
21978				
21979		g_objTextPanel.setOptions(objOptions);
21980		
21981		g_objTextPanel.refresh(true, true);
21982		
21983		handlePanelHeight("positionTextPanelWide");
21984		g_objTextPanel.positionPanel();
21985	}
21986	
21987	/**
21988	 * hide top panel
21989	 */
21990	function hideTopPanel(){
21991				
21992		if(!g_objTopPanel)
21993			return(false);
21994		
21995		g_objTopPanel.hide();
21996	}
21997	
21998	
21999	/**
22000	 * show top panel
22001	 */
22002	function showTopPanel(){
22003		
22004		if(!g_objTopPanel)
22005			return(false);
22006		
22007		g_objTopPanel.show();
22008	}
22009	
22010	
22011	function __________COMPACT_ONLY_________(){};
22012
22013	/**
22014	 * handle slider image height according the textpanel height
22015	 * refresh the slider if the height is not in place
22016	 */
22017	function handleCompactHeight(objImageSize){
22018				
22019		if(g_temp.isOpened == false)
22020			return(false);
22021		
22022		if(!g_objTextPanel)
22023			return(false);
22024		
22025		if(!g_objSlider)
22026			return(false);
22027		
22028		var wrapperSize = g_functions.getElementSize(g_objWrapper);
22029		var textPanelSize = g_objTextPanel.getSize();
22030		
22031		if(textPanelSize.width == 0 || textPanelSize.height > 120)
22032			return(false);
22033		
22034		if(!objImageSize){
22035			var objImage = g_objSlider.getSlideImage();
22036			var objImageSize = g_functions.getElementSize(objImage);
22037		}
22038		
22039		if(objImageSize.height == 0 || objImageSize.width == 0)
22040			return(false);
22041		
22042		//check elements end size
22043		var totalBottom = objImageSize.bottom + textPanelSize.height;
22044		
22045		if(totalBottom < wrapperSize.height)
22046			return(false);
22047		
22048		var sliderOptions = g_objSlider.getOptions();
22049		
22050		var imagePaddingBottom = textPanelSize.height;
22051		
22052		if(imagePaddingBottom != sliderOptions.slider_image_padding_bottom){
22053			
22054			var objOptions = {
22055					slider_image_padding_bottom: imagePaddingBottom
22056			};
22057			
22058			if(g_objSlider.isAnimating() == false){
22059				g_objSlider.setOptions(objOptions);
22060				g_objSlider.refreshSlideItems();
22061				return(true);
22062			}
22063			
22064		}
22065		
22066		return(false);
22067	}
22068	
22069	/**
22070	 * set text panel top of compact mode
22071	 */
22072	function setCompactTextpanelTop(objImageSize, positionPanel){
22073		
22074		if(!objImageSize){
22075			var objImage = g_objSlider.getSlideImage();
22076			var objImageSize = g_functions.getElementSize(objImage);
22077		}
22078		
22079		g_temp.textPanelTop = objImageSize.bottom;
22080		
22081		if(positionPanel === true)
22082			g_objTextPanel.positionPanel(g_temp.textPanelTop, g_temp.textPanelLeft);
22083	}
22084	
22085	
22086	/**
22087	 * handle text panel width on compact mode, 
22088	 * run when the image is ready. 
22089	 * Set top position of the panel as well
22090	 * position numbers as well
22091	 */
22092	function handleCompactTextpanelSizes(showTextpanel){
22093			
22094		var wrapperSize = g_functions.getElementSize(g_objWrapper);
22095		var objImage = g_objSlider.getSlideImage();
22096		var objImageSize = g_functions.getElementSize(objImage);
22097		
22098		if(objImageSize.width == 0)
22099			return(false);
22100		
22101		
22102		g_temp.textPanelLeft = objImageSize.left;
22103		g_temp.textPanelTop = objImageSize.bottom;
22104
22105		var textPanelWidth = objImageSize.width;
22106		
22107		if(g_objNumbers){
22108			
22109			var objNumbersSize = g_functions.getElementSize(g_objNumbers);
22110			textPanelWidth -= objNumbersSize.width;
22111			
22112			//place numbers object
22113			var numbersLeft = objImageSize.right - objNumbersSize.width;
22114			g_functions.placeElement(g_objNumbers, numbersLeft, g_temp.textPanelTop);
22115		}
22116			
22117			
22118		if(g_objTextPanel){
22119			g_objTextPanel.show();
22120			g_objTextPanel.refresh(true, true, textPanelWidth);
22121			setCompactTextpanelTop(objImageSize);
22122		}
22123		
22124		var isChanged = handleCompactHeight(objImageSize);
22125		
22126		if(isChanged == false){
22127			
22128			g_temp.positionFrom = "handleCompactTextpanelSizes";
22129			
22130			if(g_objTextPanel){
22131				g_objTextPanel.positionPanel(g_temp.textPanelTop, g_temp.textPanelLeft);
22132				if(showTextpanel === true){
22133					showTextpanel();
22134					showNumbers();
22135				}
22136			}
22137			
22138		}
22139		
22140	}
22141	
22142	
22143	
22144	/**
22145	 * return that current slider image is in place
22146	 */
22147	function isSliderImageInPlace(){
22148
22149		if(g_objSlider.isCurrentSlideType("image") == false)
22150			return(true);
22151		
22152		var isImageInPlace = (g_objSlider.isCurrentImageInPlace() == true);
22153				
22154		return(isImageInPlace);
22155	}
22156	
22157	
22158	/**
22159	 * position the arrows inside mode
22160	 */
22161	function positionArrowsInside(toShow, isAnimation){
22162				
22163		if(g_temp.isArrowsInside == false)
22164			return(false);
22165		
22166		if(!g_objArrowLeft)
22167			return(false);
22168		
22169		var isImageInPlace = isSliderImageInPlace();
22170		
22171		g_objArrowLeft.show();
22172		g_objArrowRight.show();
22173		
22174		g_temp.positionFrom = "positionArrowsInside";
22175		
22176		if(g_temp.isArrowsOnHoverMode == true && isImageInPlace == true && isMouseInsideImage() == false)
22177			hideArrows(true);
22178		
22179		if(isImageInPlace == false){
22180			var leftArrowLeft = g_functions.getElementRelativePos(g_objArrowLeft, "left", g_options.lightbox_arrows_offset);
22181			var leftArrowTop = g_functions.getElementRelativePos(g_objArrowLeft, "middle");
22182						
22183			var rightArrowLeft = g_functions.getElementRelativePos(g_objArrowRight, "right", g_options.lightbox_arrows_offset);
22184			var rightArrowTop = leftArrowTop;
22185
22186		}else{
22187			
22188			var objImage = g_objSlider.getSlideImage();
22189			var objImageSize = g_functions.getElementSize(objImage);
22190			var objSliderSize = g_functions.getElementSize(g_objSlider.getElement());
22191						
22192			var leftArrowLeft = g_functions.getElementRelativePos(g_objArrowLeft, "left", 0, objImage) + objImageSize.left + g_options.lightbox_arrows_inside_offset;
22193			var leftArrowTop = g_functions.getElementRelativePos(g_objArrowLeft, "middle", 0, objImage) + objImageSize.top;
22194			var rightArrowLeft = g_functions.getElementRelativePos(g_objArrowLeft, "right", 0, objImage) + objImageSize.left - g_options.lightbox_arrows_inside_offset;
22195			var rightArrowTop = leftArrowTop;
22196			
22197		}
22198		
22199		
22200		//place the image with animation or not
22201		if(isAnimation === true){
22202
22203			var objCssLeft = {
22204					left: leftArrowLeft,
22205					top: leftArrowTop
22206			};
22207			
22208			var objCssRight = {
22209					left: rightArrowLeft,
22210					top: rightArrowTop
22211			};
22212			
22213			g_objArrowLeft.stop().animate(objCssLeft,{
22214				duration: g_temp.fadeDuration
22215			});
22216			
22217			g_objArrowRight.stop().animate(objCssRight,{
22218				duration: g_temp.fadeDuration
22219			});
22220			
22221			
22222		}else{
22223			g_objArrowLeft.stop();
22224			g_objArrowRight.stop();
22225			
22226			g_functions.placeElement(g_objArrowLeft, leftArrowLeft, leftArrowTop);
22227			g_functions.placeElement(g_objArrowRight, rightArrowLeft, rightArrowTop);
22228		}
22229		
22230		
22231		if(toShow == true)
22232			showArrows(isAnimation);
22233		
22234	}
22235	
22236	
22237	
22238	/**
22239	 * position close button for compact type
22240	 */
22241	function positionCloseButton(toShow, isAnimation){
22242		
22243		g_temp.positionFrom = null;
22244		
22245		var isImageInPlace = isSliderImageInPlace();
22246		
22247		var minButtonTop = 2;
22248		var maxButtonLeft = g_functions.getElementRelativePos(g_objButtonClose, "right", 2, g_objWrapper);
22249		
22250		if(isImageInPlace == false){	//put image to corner
22251			
22252			var closeButtonTop = minButtonTop;
22253			var closeButtonLeft = maxButtonLeft;
22254			
22255		}else{
22256			var objImage = g_objSlider.getSlideImage();
22257			var objImageSize = g_functions.getElementSize(objImage);
22258			var objSliderSize = g_functions.getElementSize(g_objSlider.getElement());
22259			var objButtonSize = g_functions.getElementSize(g_objButtonClose);
22260			
22261			//some strange bug
22262			if(objSliderSize.top == objSliderSize.height)	
22263				objSliderSize.top = 0;
22264			
22265			var closeButtonLeft = objSliderSize.left + objImageSize.right - objButtonSize.width / 2 + g_options.lightbox_compact_closebutton_offsetx;
22266			var closeButtonTop = objSliderSize.top + objImageSize.top - objButtonSize.height / 2 - g_options.lightbox_compact_closebutton_offsety;
22267			
22268			if(closeButtonTop < minButtonTop)
22269				closeButtonTop = minButtonTop;
22270			
22271			if(closeButtonLeft > maxButtonLeft)
22272				closeButtonLeft = maxButtonLeft;
22273			
22274		}
22275		
22276		//place the image with animation or not
22277		if(isAnimation === true){
22278			var objCss = {
22279					left: closeButtonLeft,
22280					top: closeButtonTop
22281			};
22282			
22283			g_objButtonClose.stop().animate(objCss,{
22284				duration: g_temp.fadeDuration
22285			});
22286			
22287		}else{
22288			g_objButtonClose.stop();
22289			g_functions.placeElement(g_objButtonClose, closeButtonLeft, closeButtonTop);
22290		}
22291		
22292		if(toShow === true)
22293			showCloseButton(isAnimation);
22294		
22295	}
22296	
22297	
22298	/**
22299	 * hide close button
22300	 */
22301	function hideCompactElements(){
22302		
22303		if(g_objButtonClose)
22304			g_objButtonClose.stop().fadeTo(g_temp.fadeDuration, 0);
22305		
22306		hideTextPanel();
22307		
22308		hideNumbers();
22309		
22310		g_temp.positionFrom = "hideCompactElements";
22311		if(g_temp.isArrowsInside == true)
22312			hideArrows();
22313	}
22314
22315	
22316	/**
22317	 * actual hide all compact type elements
22318	 */
22319	function actualHideCompactElements(){
22320		
22321		if(g_objButtonClose)
22322			g_objButtonClose.hide();
22323		
22324		if(g_objArrowLeft && g_temp.isArrowsInside == true){
22325			g_objArrowLeft.hide();
22326			g_objArrowRight.hide();
22327		}
22328		
22329		if(g_objNumbers)
22330			g_objNumbers.hide();
22331		
22332		if(g_objTextPanel)
22333			g_objTextPanel.hide();
22334		
22335	}
22336	
22337	
22338	function __________COMMON_________(){};
22339	
22340	
22341	/**
22342	 * position the elements
22343	 */
22344	function positionElements(){
22345						
22346		var size = g_functions.getElementSize(g_objWrapper);
22347		
22348		//position top panel:
22349		if(g_objTopPanel)
22350			g_functions.setElementSizeAndPosition(g_objTopPanel, 0, 0, size.width, g_temp.topPanelHeight);
22351		
22352		//position arrows
22353		if(g_objArrowLeft && g_temp.isArrowsInside == false){
22354			
22355			if(g_options.lightbox_hide_arrows_onvideoplay == true){
22356				g_objArrowLeft.show();
22357				g_objArrowRight.show();
22358			}
22359			
22360			g_functions.placeElement(g_objArrowLeft, "left", "middle", g_options.lightbox_arrows_offset);
22361			g_functions.placeElement(g_objArrowRight, "right", "middle", g_options.lightbox_arrows_offset);
22362		}		
22363		
22364		if(g_temp.isCompact == false)
22365			g_functions.placeElement(g_objButtonClose, "right", "top", 2, 2);
22366		
22367		//place text panel
22368		if(g_objTextPanel){
22369			
22370			g_temp.positionFrom = "positionElements";
22371			
22372			if(g_temp.isCompact == false)
22373				positionTextPanelWide(size);
22374			else{
22375				showTextPanel();
22376				showNumbers();
22377			}
22378			
22379		}
22380		
22381		var sliderWidth = size.width;
22382		var sliderHeight = size.height;	
22383		var sliderTop = 0;
22384		var sliderLeft = 0;
22385		
22386		if(g_objSlider){
22387			
22388			if(g_objTopPanel){
22389				var topPanelHeight = g_objTopPanel.height();
22390				var objOptions = {
22391						slider_image_padding_top: topPanelHeight
22392				};
22393				g_objSlider.setOptions(objOptions);
22394			}
22395			
22396			g_objSlider.setSize(sliderWidth, sliderHeight);
22397			g_objSlider.setPosition(sliderLeft, sliderTop);
22398		}
22399		
22400	}
22401	
22402	
22403	/**
22404	 * hide the text panel
22405	 */
22406	function hideTextPanel(){
22407		
22408		if(g_objTextPanel)
22409			g_objTextPanel.getElement().stop().fadeTo(g_temp.fadeDuration, 0);
22410		
22411	}
22412	
22413	
22414	/**
22415	 * hide the numbers text
22416	 */
22417	function hideNumbers(){
22418		
22419		if(g_objNumbers)
22420			g_objNumbers.stop().fadeTo(g_temp.fadeDuration, 0);
22421	}
22422	
22423	
22424	/**
22425	 * is mouse inside image
22426	 */
22427	function isMouseInsideImage(){
22428		if(!g_temp.lastMouseX)
22429			return(true);
22430		var obj = {
22431				pageX: g_temp.lastMouseX, 
22432				pageY: g_temp.lastMouseY
22433			};
22434	
22435		var isMouseInside = g_objSlider.isMouseInsideSlideImage(obj);
22436		
22437		return(isMouseInside);
22438	}
22439	
22440	
22441	/**
22442	 * hide the arrows
22443	 */
22444	function hideArrows(noAnimation, isForce){
22445		
22446		if(!g_objArrowLeft)
22447			return(false);
22448				
22449		//don't hide the arrows if mouse inside image
22450		if(g_temp.isArrowsOnHoverMode == true && isForce === false){
22451			if(isMouseInsideImage() == true);
22452				return(true);
22453		}
22454		
22455		if(noAnimation === true){
22456			g_objArrowLeft.stop().fadeTo(0, 0);
22457			g_objArrowRight.stop().fadeTo(0, 0);
22458		}else{
22459			g_objArrowLeft.stop().fadeTo(g_temp.fadeDuration, 0);
22460			g_objArrowRight.stop().fadeTo(g_temp.fadeDuration, 0);
22461		}
22462				
22463	}
22464	
22465	/**
22466	 * get if the arrows are hidden
22467	 */
22468	function isArrowsHidden(){
22469		
22470		if(!g_objArrowLeft)
22471			return(true);
22472		if(g_objArrowLeft.is(":visible") == false)
22473			return(true);
22474		
22475		var opacity = g_objArrowLeft.css("opacity");
22476		if(opacity != 1)
22477			return(true);
22478		
22479		return(false);
22480	}
22481	
22482	/**
22483	 * show the arrows
22484	 */
22485	function showArrows(noStop, fromHover){
22486		
22487		if(!g_objArrowLeft)
22488			return(false);
22489		
22490		//don't show every time on arrowsonhover mode
22491		if(g_temp.isArrowsOnHoverMode == true && fromHover !== true && isSli
22491derImageInPlace() == true)
22492			return(true);
22493		
22494		//don't show if swiping
22495		if(g_objSlider.isSwiping() == true)
22496			return(true);
22497			
22498		if(noStop !== true){
22499			g_objArrowLeft.stop();
22500			g_objArrowRight.stop();
22501		}
22502		
22503		g_objArrowLeft.fadeTo(g_temp.fadeDuration, 1);
22504		g_objArrowRight.fadeTo(g_temp.fadeDuration, 1);
22505		
22506	}
22507
22508	
22509	
22510	
22511	
22512	/**
22513	 * show close button
22514	 */
22515	function showCloseButton(noStop){
22516		
22517		if(noStop !== true)
22518			g_objButtonClose.stop();
22519		
22520		g_objButtonClose.fadeTo(g_temp.fadeDuration, 1);
22521	}
22522	
22523	
22524	/**
22525	 * update text panel text of the curren item
22526	 */
22527	function updateTextPanelText(currentItem){
22528		
22529		if(!g_objTextPanel)
22530			return(false);
22531		
22532		if(!currentItem)
22533			var currentItem = g_objSlider.getCurrentItem();
22534		
22535		g_objTextPanel.setTextPlain(currentItem.title, currentItem.description);
22536	}
22537
22538	
22539	/**
22540	 * update numbers text
22541	 */
22542	function updateNumbersText(currentItem){
22543		
22544		if(!g_objNumbers)
22545			return(false);
22546		
22547		if(!currentItem)
22548			var currentItem = g_objSlider.getCurrentItem();
22549		
22550		var numItems = g_gallery.getNumItems();
22551		var numCurrentItem = currentItem.index + 1;
22552		g_objNumbers.html(numCurrentItem + " / " + numItems);
22553	}
22554	
22555	
22556	/**
22557	 * show the text panel
22558	 */
22559	function showTextPanel(){
22560		
22561		if(!g_objTextPanel)
22562			return(false);
22563		
22564		g_objTextPanel.getElement().show().stop().fadeTo(g_temp.fadeDuration, 1);
22565		
22566	}
22567
22568	
22569	/**
22570	 * Show the numbers object
22571	 */
22572	function showNumbers(){
22573		
22574		if(g_objNumbers)
22575			g_objNumbers.stop().fadeTo(g_temp.fadeDuration, 1);
22576	}
22577	
22578	
22579	function __________EVENTS_________(){};
22580	
22581	
22582	/**
22583	 * on start dragging slider item event. hide the elements
22584	 */
22585	function onSliderDragStart(){
22586		if(g_temp.isCompact == false)
22587			return(true);
22588		
22589		hideCompactElements();
22590	}
22591
22592	
22593	/**
22594	 * on zoom change
22595	 * move the assets of compact to their places
22596	 */
22597	function onZoomChange(){
22598		if(g_temp.isCompact == false)
22599			return(true);
22600		
22601		g_temp.positionFrom = "onZoomChange";
22602	
22603		positionCloseButton(false, true);
22604		positionArrowsInside(false, true);
22605		
22606		//handle compact text panel mode
22607		if(g_temp.isCompact == true){
22608			var isImageInPlace = (g_objSlider.isCurrentSlideType("image") && g_objSlider.isCurrentImageInPlace() == true);
22609			if(isImageInPlace == false){
22610				hideTextPanel();
22611				hideNumbers();
22612			}
22613			else{
22614				g_temp.positionFrom = "onZoomChange";
22615				showTextPanel();
22616				showNumbers();
22617			}
22618		}
22619		
22620	}
22621	
22622
22623	/**
22624	 * after return slider to it's place
22625	 * show close button
22626	 */
22627	function onSliderAfterReturn(){
22628		
22629		if(g_temp.isCompact == false)
22630			return(true);
22631		
22632		g_temp.positionFrom = "onSliderAfterReturn";
22633		
22634		positionCloseButton(true);
22635		positionArrowsInside(true);
22636		
22637		var isChanged = handleCompactHeight();
22638		if(isChanged == false)
22639			handleCompactTextpanelSizes();
22640		
22641		showTextPanel();
22642		showNumbers();
22643	}
22644	
22645	
22646	/**
22647	 * after put image to the slide
22648	 * position compact elements
22649	 */
22650	function onSliderAfterPutImage(data, objSlide){
22651				
22652		objSlide = jQuery(objSlide);
22653				
22654		if(g_temp.isCompact == false)
22655			return(true);
22656
22657		if(g_objSlider.isSlideCurrent(objSlide) == false)
22658			return(true);
22659				
22660		g_temp.positionFrom = "onSliderAfterPutImage";
22661		
22662		positionCloseButton(true);
22663		
22664		positionArrowsInside(true);
22665		
22666		handleCompactTextpanelSizes();
22667	}
22668	
22669	
22670	/**
22671	 * on slider transition end, handle panel height
22672	 */
22673	function onSliderTransitionEnd(){
22674		
22675		var sliderOptions = g_objSlider.getOptions();
22676		var imagePaddingTop = sliderOptions.slider_image_padding_top;
22677		
22678		//handle wide
22679		if(g_objTopPanel){
22680			var panelHeight = g_objTopPanel.height();
22681			
22682			if(panelHeight != imagePaddingTop)
22683				refreshSliderItem(panelHeight);
22684		}
22685		
22686		//handle compact
22687		if(g_temp.isCompact == true){
22688			
22689			updateTextPanelText();
22690			updateNumbersText();
22691			
22692			g_temp.positionFrom = "onSliderTransitionEnd";
22693			
22694			positionCloseButton(true);
22695			positionArrowsInside(true);
22696
22697			if(g_objSlider.isSlideActionActive() == false){
22698				var isChanged = handleCompactHeight();
22699				if(isChanged == false)
22700					handleCompactTextpanelSizes();
22701			}
22702			
22703			showTextPanel();
22704			showNumbers();
22705			
22706		}
22707		
22708	}
22709	
22710		
22711	/**
22712	 * on item change
22713	 * update numbers text and text panel text/position
22714	 */
22715	function onItemChange(data, currentItem){
22716		
22717		if(g_temp.isCompact == false){	//wide mode
22718			
22719			if(g_objNumbers)
22720				updateNumbersText(currentItem);
22721			
22722			if(g_objTextPanel){
22723				updateTextPanelText(currentItem);
22724				
22725				//update panel height only if the lightbox is already opened, and the items changed within it.
22726				if(g_temp.isRightNowOpened == false){
22727					g_objTextPanel.positionElements(false);
22728					handlePanelHeight("onchange");
22729					g_objTextPanel.positionPanel();
22730				}
22731				
22732			}
22733			
22734		}else{
22735			
22736			if(g_objSlider.isAnimating() == false){
22737				
22738				if(g_objTextPanel)
22739					updateTextPanelText(currentItem);
22740				
22741				if(g_objNumbers)
22742					updateNumbersText(currentItem);
22743			}
22744		
22745		}
22746		
22747		
22748		//trigger lightbox init event
22749		if(g_temp.isSliderChangedOnce == false){
22750			g_temp.isSliderChangedOnce = true;
22751			g_objThis.trigger(t.events.LIGHTBOX_INIT);
22752		}
22753		
22754	}
22755	
22756	
22757	/**
22758	 * on slider click
22759	 */
22760	function onSliderClick(data, event){
22761		
22762		var slideType = g_objSlider.getSlideType();
22763		if(slideType != "image" && g_temp.isCompact == false && g_objSlider.isSlideActionActive() )
22764			return(true);
22765		
22766		var isPreloading = g_objSlider.isPreloading();
22767		if(isPreloading == true){
22768			t.close("slider");
22769			return(true);
22770		}
22771		
22772		//close the lightbox on empty space click
22773		if(g_options.lightbox_close_on_emptyspace == true){
22774			
22775			var isInside = g_objSlider.isMouseInsideSlideImage(event);
22776			
22777			if(isInside == false)
22778				t.close("slider_inside");
22779		}
22780		
22781	}
22782	
22783	
22784	/**
22785	 * on lightbox resize
22786	 */
22787	function onResize(){
22788		
22789		positionElements();
22790	}
22791	
22792	
22793	
22794	/**
22795	 * on start play - hide the side buttons
22796	 */
22797	function onPlayVideo(){
22798		
22799		if(g_objTopPanel){
22800			hideTopPanel();
22801		}else{
22802			if(g_objNumbers)
22803				g_objNumbers.hide();
22804		}
22805		
22806		if(g_objArrowLeft && g_options.lightbox_hide_arrows_onvideoplay == true){
22807			g_objArrowLeft.hide();			
22808			g_objArrowRight.hide();			
22809		}
22810		
22811	}
22812	
22813	
22814	/**
22815	 * on stop video - show the side buttons
22816	 */
22817	function onStopVideo(){
22818
22819		if(g_objTopPanel){
22820			showTopPanel();
22821			handlePanelHeight("onStopVideo");
22822		}else{
22823			
22824			if(g_objNumbers)
22825				g_objNumbers.show();
22826		}
22827		
22828		if(g_objArrowLeft && g_options.lightbox_hide_arrows_onvideoplay == true){
22829			g_objArrowLeft.show();
22830			g_objArrowRight.show();			
22831		}
22832		
22833	}
22834	
22835	/**
22836	 * on gallery keypres, do operations
22837	 */
22838	function onKeyPress(data, key, event){
22839		
22840		var isScrollKey = false;
22841		
22842		switch(key){
22843			case 27:		//escape - close lightbox
22844				if(g_temp.isOpened == true)
22845					t.close("keypress");
22846			break;
22847			case 38:	//up and down arrows
22848			case 40:
22849			case 33:	//page up and down
22850			case 34:
22851				isScrollKey = true;
22852			break;
22853		}
22854		
22855		if(g_temp.isOpened == true && isScrollKey == true)
22856			event.preventDefault();
22857		
22858		
22859	}
22860	
22861	/**
22862	 * on image mouse enter event
22863	 */
22864	function onImageMouseEnter(){
22865		
22866		if(g_temp.isArrowsOnHoverMode == true)
22867			showArrows(false, true);
22868		
22869	}
22870	
22871	/**
22872	 * on image mouse leave
22873	 */
22874	function onImageMouseLeave(event){
22875		
22876		g_temp.positionFrom = "hideCompactElements";
22877		
22878		if(g_temp.isArrowsOnHoverMode == true && isSliderImageInPlace() == true)
22879			hideArrows(false, true);
22880		
22881	}
22882	
22883	
22884	/**
22885	 * on mouse move event
22886	 * show arrows if inside image
22887	 */
22888	function onMouseMove(event){
22889		 g_temp.lastMouseX = event.pageX;
22890		 g_temp.lastMouseY = event.pageY;
22891		
22892		 var isHidden = isArrowsHidden()
22893		 
22894		 
22895		 if(isHidden == true && isMouseInsideImage() && g_objSlider.isAnimating() == false){
22896			 g_temp.positionFrom = "onMouseMove";
22897			 if(g_objArrowLeft && g_objArrowLeft.is(":animated") == false)
22898				 showArrows(false, true);
22899		 }
22900		 
22901	}
22902
22903	
22904	/**
22905	 * on mouse wheel
22906	 */
22907	function onMouseWheel(event, delta, deltaX, deltaY){
22908		
22909		if(g_temp.isOpened == false)
22910			return(true);
22911		
22912		switch(g_options.gallery_mousewheel_role){
22913			default:
22914			case "zoom":
22915				var slideType = g_objSlider.getSlideType();
22916				if(slideType != "image")
22917					event.preventDefault();
22918			break;
22919			case "none":
22920				event.preventDefault();
22921			break;
22922			case "advance":
22923				g_gallery.onGalleryMouseWheel(event, delta, deltaX, deltaY);
22924			break;
22925		}
22926		
22927	}
22928	
22929	
22930	/**
22931	 * init events
22932	 */
22933	function initEvents(){
22934		
22935		g_objOverlay.on("touchstart", function(event){
22936			event.preventDefault();
22937		});
22938		
22939		g_objOverlay.on("touchend", function(event){
22940			t.close("overlay");
22941		});
22942		
22943		
22944		g_functions.addClassOnHover(g_objArrowRight, "ug-arrow-hover");
22945		g_functions.addClassOnHover(g_objArrowLeft, "ug-arrow-hover");
22946		
22947		g_functions.addClassOnHover(g_objButtonClose);
22948		
22949		g_gallery.setNextButton(g_objArrowRight);
22950		g_gallery.setPrevButton(g_objArrowLeft);
22951		
22952		g_objButtonClose.click(function(){
22953			t.close("button");
22954		});
22955		
22956		g_objGallery.on(g_gallery.events.ITEM_CHANGE, onItemChange);
22957		
22958		if(g_objSlider){
22959			jQuery(g_objSlider).on(g_objSlider.events.TRANSITION_END, onSliderTransitionEnd);
22960			
22961			//on slider click event
22962			jQuery(g_objSlider).on(g_objSlider.events.CLICK, onSliderClick);
22963			
22964			//on slider video 
22965			var objVideo = g_objSlider.getVideoObject();
22966					
22967			jQuery(objVideo).on(objVideo.events.PLAY_START, onPlayVideo);
22968			jQuery(objVideo).on(objVideo.events.PLAY_STOP, onStopVideo);
22969			
22970			//handle close button hide / appear
22971			jQuery(g_objSlider).on(g_objSlider.events.START_DRAG, onSliderDragStart);
22972			jQuery(g_objSlider).on(g_objSlider.events.TRANSITION_START, onSliderDragStart);
22973			
22974			jQuery(g_objSlider).on(g_objSlider.events.AFTER_DRAG_CHANGE, onSliderAfterReturn);
22975			jQuery(g_objSlider).on(g_objSlider.events.AFTER_RETURN, onSliderAfterReturn);
22976			jQuery(g_objSlider).on(g_objSlider.events.AFTER_PUT_IMAGE, onSliderAfterPutImage);
22977			
22978			jQuery(g_objSlider).on(g_objSlider.events.ZOOM_CHANGE, onZoomChange);
22979			
22980			jQuery(g_objSlider).on(g_objSlider.events.IMAGE_MOUSEENTER, onImageMouseEnter);
22981			jQuery(g_objSlider).on(g_objSlider.events.IMAGE_MOUSELEAVE, onImageMouseLeave);
22982
22983		}
22984		
22985		//on resize
22986		 jQuery(window).resize(function(){
22987			 
22988			 if(g_temp.isOpened == false)
22989				 return(true);
22990			 
22991			 g_functions.whenContiniousEventOver("lightbox_resize", onResize, 100);
22992		 });
22993		 
22994		 g_objGallery.on(g_gallery.events.GALLERY_KEYPRESS, onKeyPress);
22995		 
22996		 //store last mouse x and y
22997		 if(g_temp.isArrowsOnHoverMode == true){
22998			 
22999			 jQuery(document).bind('mousemove', onMouseMove);
23000		 
23001		 }
23002		
23003		//on mouse wheel - disable functionality if video
23004		g_objWrapper.on("mousewheel", onMouseWheel);
23005
23006	}
23007
23008	
23009	/**
23010	 * destroy the lightbox events and the html it created
23011	 */
23012	this.destroy = function(){
23013		
23014		jQuery(document).unbind("mousemove");
23015		
23016		g_objOverlay.off("touchstart");
23017		g_objOverlay.off("touchend");
23018		g_objButtonClose.off("click");
23019		g_objGallery.off(g_gallery.events.ITEM_CHANGE);
23020		
23021		if(g_objSlider){
23022			jQuery(g_objSlider).off(g_objSlider.events.TRANSITION_END);
23023			jQuery(g_objSlider).off(g_objSlider.events.CLICK);
23024			jQuery(g_objSlider).off(g_objSlider.events.START_DRAG);
23025			jQuery(g_objSlider).off(g_objSlider.events.TRANSITION_START);
23026			jQuery(g_objSlider).off(g_objSlider.events.AFTER_DRAG_CHANGE);
23027			jQuery(g_objSlider).off(g_objSlider.events.AFTER_RETURN);
23028			
23029			var objVideo = g_objSlider.getVideoObject();
23030			jQuery(objVideo).off(objVideo.events.PLAY_START);
23031			jQuery(objVideo).off(objVideo.events.PLAY_STOP);
23032
23033			jQuery(g_objSlider).on(g_objSlider.events.IMAGE_MOUSEENTER, onImageMouseEnter);
23034			jQuery(g_objSlider).on(g_objSlider.events.IMAGE_MOUSELEAVE, onImageMouseLeave);
23035			
23036			g_objSlider.destroy();
23037		}
23038		
23039		jQuery(window).unbind("resize");
23040		g_objGallery.off(g_gallery.events.GALLERY_KEYPRESS, onKeyPress);
23041		
23042		g_objWrapper.off("mousewheel");
23043		
23044		//remove the html
23045		g_objWrapper.remove();
23046	}
23047	
23048	
23049	/**
23050	 * open the lightbox with some item index
23051	 */
23052	this.open = function(index){
23053		
23054		var objItem = g_gallery.getItem(index);
23055		
23056		g_temp.isOpened = true;
23057		
23058		//set if the panel right now opened
23059		g_temp.isRightNowOpened = true;
23060		setTimeout(function(){g_temp.isRightNowOpened = false},100);
23061		
23062		if(g_objSlider){
23063			g_objSlider.setItem(objItem, "lightbox_open");
23064		}
23065		
23066		if(g_objTextPanel){
23067			g_objTextPanel.setTextPlain(objItem.title, objItem.description);
23068		}
23069		
23070		g_objOverlay.stop().fadeTo(0,0);
23071		g_objWrapper.show();
23072		g_objWrapper.fadeTo(0,1);
23073		
23074		//show the overlay
23075		g_objOverlay.stop().fadeTo(g_temp.fadeDuration, g_options.lightbox_overlay_opacity);
23076		
23077		positionElements();
23078		
23079		if(g_temp.isCompact == true){
23080			
23081			var isPreloading = g_objSlider.isPreloading();
23082			if(isPreloading == true){
23083				
23084				actualHideCompactElements();
23085				
23086			}else{
23087				
23088				//hide only arrows if they are inside
23089				if(g_temp.isArrowsInside == true){
23090					g_objArrowLeft.hide();
23091					g_objArrowRight.hide();
23092				}
23093				
23094			}
23095				
23096		}
23097		
23098		if(g_objSlider)
23099			g_objSlider.startSlideAction();
23100		
23101		//trigger gallery event
23102		g_objGallery.trigger(g_gallery.events.OPEN_LIGHTBOX, objItem);
23103		
23104	}
23105	
23106	
23107	/**
23108	 * close the lightbox
23109	 */
23110	this.close = function(fromWhere){
23111				
23112		g_temp.isOpened = false;
23113		
23114		if(g_temp.isCompact == true)
23115			hideCompactElements();
23116		
23117		if(g_objSlider)
23118			g_objSlider.stopSlideAction();
23119		
23120		var slideType = g_objSlider.getSlideType();
23121				
23122		if(slideType != "image")
23123			g_objWrapper.hide();
23124		else{
23125			g_objWrapper.fadeTo(g_temp.fadeDuration,0,function(){
23126				g_objWrapper.hide();
23127			});
23128		}
23129
23130		g_objGallery.trigger(g_gallery.events.CLOSE_LIGHTBOX);
23131		
23132	}
23133	
23134	
23135	/**
23136	 * external init function
23137	 */
23138	this.init = function(gallery, customOptions){
23139		
23140		initLightbox(gallery, customOptions);
23141	}
23142	
23143	
23144	/**
23145	 * switch to wide mode from compact mode
23146	 */
23147	function switchToWide(){
23148		g_temp.isCompact = false;
23149		modifyOptions();
23150		
23151		g_temp.isArrowsInside = false;
23152		g_temp.isArrowsOnHoverMode = false;
23153	
23154		g_options = jQuery.extend({}, g_temp.originalOptions);
23155		
23156		g_options.lightbox_arrows_position = "sides";
23157		
23158		g_objSlider.setOptions(g_options);
23159	}
23160	
23161	
23162	/**
23163	 * external put html function
23164	 */
23165	this.putHtml = function(){
23166		
23167		//check if switch to wide mode
23168		var isSmallWindow = g_gallery.isSmallWindow();
23169		
23170		if(isSmallWindow && g_temp.isCompact == true)
23171			switchToWide();
23172		
23173		putLightboxHtml();
23174	}
23175	
23176	
23177	/**
23178	 * run lightbox elements
23179	 */
23180	this.run = function(){
23181		
23182		setProperties();
23183		
23184		if(g_objSlider)
23185			g_objSlider.run();
23186		
23187		initEvents();
23188	}
23189	
23190	
23191	
23192}
23193
23194
23195
23196/**
23197 * carousel class
23198 */
23199function UGCarousel(){
23200
23201	var t = this, g_objThis = jQuery(this);
23202	var g_gallery = new UniteGalleryMain(), g_objGallery, g_objWrapper;	
23203	var g_functions = new UGFunctions(), g_arrItems, g_objTileDesign = new UGTileDesign();
23204	var g_thumbs = new UGThumbsGeneral(), g_objCarouselWrapper, g_objInner, arrOrigTiles = [];
23205	
23206	var g_options = {
23207			carousel_padding: 8,							//padding at the sides of the carousel
23208			carousel_space_between_tiles: 20,				//space between tiles
23209			carousel_navigation_numtiles:3,					//number of tiles to scroll when user clicks on next/prev button
23210			carousel_scroll_duration:500,					//duration of scrolling to tile
23211			carousel_scroll_easing:"easeOutCubic",			//easing of scrolling to tile animation
23212			
23213			carousel_autoplay: true,						//true,false - autoplay of the carousel on start
23214			carousel_autoplay_timeout: 3000,				//autoplay timeout
23215			carousel_autoplay_direction: "right",			//left,right - autoplay direction
23216			carousel_autoplay_pause_onhover: true,			//pause the autoplay on mouse over
23217			carousel_vertical_scroll_ondrag: false			//vertical screen scroll on carousel drag
23218	};
23219	
23220	this.events = {
23221			START_PLAY: "carousel_start_play",
23222			PAUSE_PLAY: "carousel_pause_play",
23223			STOP_PLAY: "carousel_stop_play"
23224	};
23225	
23226	var g_temp = {
23227			eventSizeChange: "thumb_size_change",
23228			isFirstTimeRun:true,  //if run once
23229			carouselMaxWidth: null,
23230			tileWidth:0,
23231			initTileWidth:0,
23232			initTileHeight:0,
23233			sideSpace:1500,				//the space that must be filled with items
23234			spaceActionSize:500,
23235			numCurrent:0,
23236			touchActive: false,
23237			startInnerPos: 0,
23238			lastTime:0,
23239			startTime:0,
23240			startMousePos:0,
23241			lastMousePos:0,
23242			scrollShortDuration: 200,
23243			scrollShortEasing: "easeOutQuad",
23244			handle:null,
23245			isPlayMode: false,
23246			isPaused: false,
23247			storedEventID: "carousel"
23248	};
23249
23250	
23251	function __________GENERAL_________(){};
23252	
23253	/**
23254	 * init the gallery
23255	 */
23256	function init(gallery, customOptions){
23257		
23258		g_objects = gallery.getObjects();
23259		g_gallery = gallery;
23260		g_objGallery = jQuery(gallery);
23261		g_objWrapper = g_objects.g_objWrapper;
23262		g_arrItems = g_objects.g_arrItems;
23263		
23264		g_options = jQuery.extend(g_options, customOptions);
23265		
23266		g_objTileDesign.setFixedMode();		
23267		g_objTileDesign.setApproveClickFunction(isApproveTileClick);
23268		g_objTileDesign.init(gallery, g_options);
23269		
23270		g_thumbs = g_objTileDesign.getObjThumbs();
23271		g_options = g_objTileDesign.getOptions();
23272		
23273		g_temp.initTileWidth = g_options.tile_width;
23274		g_temp.initTileHeight = g_options.tile_height;
23275		
23276		g_temp.tileWidth = g_options.tile_width;
23277	}
23278	
23279	
23280	/**
23281	 * set the grid panel html
23282	 */
23283	function setHtml(objParent){
23284		
23285		if(!objParent)
23286			var objParent = g_objWrapper;
23287		
23288		var html = "<div class='ug-carousel-wrapper'><div class='ug-carousel-inner'></div></div>";
23289		g_objWrapper.append(html);
23290		
23291		g_objCarouselWrapper = g_objWrapper.children(".ug-carousel-wrapper");
23292		g_objInner = g_objCarouselWrapper.children(".ug-carousel-inner");
23293		
23294		g_objTileDesign.setHtml(g_objInner);
23295		
23296		g_thumbs.getThumbs().fadeTo(0,1);
23297		
23298	}
23299	
23300	
23301	/**
23302	 * resize tiles to new width / height
23303	 */
23304	function resizeTiles(newTileWidth, newTileHeight){
23305		
23306		if(!newTileHeight){
23307			
23308			var newTileHeight = g_temp.initTileHeight / g_temp.initTileWidth * newTileWidth;
23309			
23310		}
23311		
23312		g_temp.tileWidth = newTileWidth;
23313		
23314		//update all options
23315		var optUpdate = {
23316				tile_width: newTileWidth, 
23317				tile_height: newTileHeight
23318		};
23319		
23320		g_objTileDesign.setOptions(optUpdate);
23321		
23322		g_options.tile_width = newTileWidth;
23323		g_options.tile_height = newTileHeight;
23324		
23325		//resize all tiles
23326		g_objTileDesign.resizeAllTiles(newTileWidth);
23327		
23328		//reposition tiles
23329		positionTiles(true);		//must to position tiles right after size change, for inner size change
23330	}
23331	
23332	/**
23333	 * run the gallery after init and set html
23334	 */
23335	function run(){
23336		
23337		//validation
23338		if(g_temp.carouselMaxWidth === null){
23339			throw new Error("The carousel width not set");
23340			return(false);
23341		}
23342		
23343		//if the size changed, change it anyway
23344		if(g_temp.tileWidth < g_temp.initTileWidth){
23345						
23346			var newTileWidth = g_temp.carouselMaxWidth - g_options.carousel_padding * 2;
23347			if(newTileWidth > g_temp.initTileWidth)
23348				newTileWidth = g_temp.initTileWidth;
23349			
23350			resizeTiles(newTileWidth);
23351			
23352			var numTiles = g_functions.getNumItemsInSpace(g_temp.carouselMaxWidth, newTileWidth, g_options.carousel_space_between_tiles);
23353			
23354		}else{
23355			
23356			//check if need to lower tiles size
23357			var numTiles = g_functions.getNumItemsInSpace(g_temp.carouselMaxWidth, g_temp.tileWidth, g_options.carousel_space_between_tiles);
23358			
23359			//if no tiles fit, resize the tiles
23360			if(numTiles <= 0){
23361				numTiles = 1;
23362				
23363				var newTileWidth = g_temp.carouselMaxWidth - g_options.carousel_padding * 2;
23364				
23365				resizeTiles(newTileWidth);
23366			}
23367			
23368		}
23369				
23370		//set wrapper width
23371		var realWidth = g_functions.getSpaceByNumItems(numTiles, g_temp.tileWidth, g_options.carousel_space_between_tiles);
23372		realWidth += g_options.carousel_padding * 2;
23373		
23374		g_objCarouselWrapper.width(realWidth);
23375		
23376		if(g_temp.isFirstTimeRun == true){
23377			
23378			initEvents();
23379			
23380			g_objTileDesign.run();
23381			
23382			//set data indexes to tiles
23383			jQuery.each(g_arrItems, function(index, item){
23384				item.objThumbWrapper.data("index", index);
23385
23386				g_objWrapper.trigger(g_temp.eventSizeChange, [item.objThumbWrapper,true]);
23387				item.objTileOriginal = item.objThumbWrapper.clone(true, true);
23388			});
23389						
23390			positionTiles(true);		//set heights at first time
23391			
23392			if(g_options.carousel_autoplay == true)
23393				t.startAutoplay();
23394		}else{
23395			
23396			if(g_options.carousel_autoplay == true)
23397				t.pauseAutoplay();
23398			
23399			scrollToTile(0, false);
23400			
23401			if(g_options.carousel_autoplay == true)
23402				t.startAutoplay();
23403		}
23404		
23405		positionElements();
23406		
23407		g_temp.isFirstTimeRun = false;
23408	}
23409	
23410	
23411	
23412	function __________GETTERS_______(){};
23413	
23414	/**
23415	 * get inner position
23416	 */
23417	function getInnerPos(){
23418		return g_functions.getElementSize(g_objInner).left;
23419	}
23420	
23421	/**
23422	 * get mouse position
23423	 */
23424	function getMousePos(event){
23425		return g_functions.getMousePosition(event).pageX;
23426	}
23427	
23428	
23429	/**
23430	 * get all tiles
23431	 */
23432	function getTiles(){
23433		
23434		var objTiles = g_objInner.children(".ug-thumb-wrapper");
23435		
23436		return(objTiles);
23437	}
23438	
23439	
23440	/**
23441	 * get num tiles in some space
23442	 */
23443	function getNumTilesInSpace(space){
23444		
23445		var numItems = g_functions.getNumItemsInSpace(space, g_temp.tileWidth, g_options.carousel_space_between_tiles)
23446				
23447		return(numItems);
23448	}
23449	
23450	
23451	/**
23452	 * get num tiles
23453	 */
23454	function getNumTiles(){
23455		return getTiles().length;
23456	}
23457	
23458	
23459	/**
23460	 * get tile
23461	 */
23462	function getTile(numTile){
23463		validateTileNum(numTile);
23464		var objTiles = getTiles();
23465		var objTile = jQuery(objTiles[numTile]);
23466		
23467		return(objTile);
23468	}
23469	
23470	
23471	/**
23472	 * get first tile in the inner object
23473	 */
23474	function getFirstTile(){
23475				
23476		return g_objInner.children(".ug-thumb-wrapper").first();
23477	}
23478	
23479	/**
23480	 * get last tile in the inner object
23481	 */
23482	function getLastTile(){
23483		
23484		return g_objInner.children(".ug-thumb-wrapper").last();		
23485	}
23486	
23487	
23488	
23489	/**
23490	 * get clone of the time next or prev the given
23491	 */
23492	function getTileClones(objTile, numClones, dir){
23493		
23494		var index = objTile.data("index");
23495		if(index == undefined){
23496			throw new Error("every tile should have index!");			
23497		}
23498		
23499		var arrClonedItems = [];
23500		
23501		for(var i=0;i<numClones;i++){			
23502			
23503			if(dir == "prev")
23504				var itemToAdd = g_gallery.getPrevItem(index, true);
23505			else
23506				var itemToAdd = g_gallery.getNextItem(index, true);
23507			
23508			if(!itemToAdd){
23509				throw new Error("the item to add is empty");
23510			}
23511			
23512			var clonedTile = itemToAdd.objTileOriginal.clone(true, true);
23513			
23514			
23515			index = itemToAdd.index;	
23516			
23517			clonedTile.addClass("cloned");
23518			arrClonedItems.push(clonedTile);
23519		}
23520		
23521		return(arrClonedItems);
23522	}
23523	
23524	
23525	/**
23526	 * get space left from the right
23527	 */
23528	function getRemainSpaceRight(){
23529		var wrapperSize = g_functions.getElementSize(g_objCarouselWrapper);
23530		var innerSize = g_functions.getElementSize(g_objInner);
23531		
23532		var spaceTaken = innerSize.width - wrapperSize.width + innerSize.left;
23533		var spaceRemain = g_temp.sideSpace - spaceTaken;
23534				
23535		return(spaceRemain);
23536	}
23537	
23538	
23539	/**
23540	 * get remain space on the left
23541	 */
23542	function getRemainSpaceLeft(){
23543		var spaceTaken = -getInnerPos();
23544		var spaceRemain = g_temp.sideSpace - spaceTaken;
23545		return(spaceRemain);
23546	}
23547	
23548	/**
23549	 * get carousel width
23550	 */
23551	function getCarouselWidth(){
23552		
23553		var objSize = g_functions.getElementSize(g_objCarouselWrapper);
23554		return(objSize.width);
23555	}
23556	
23557	/**
23558	 * get num tiles in the carousel
23559	 */
23560	function getNumTilesInCarousel(){
23561		
23562		var width = getCarouselWidth();
23563		
23564		var numTiles = getNumTilesInSpace(width);
23565		
23566		return(numTiles);
23567	}
23568	
23569	
23570	function __________OTHER_METHODS_______(){};
23571	
23572	
23573	/**
23574	 * position existing tiles
23575	 */
23576	function positionTiles(setHeight){
23577		
23578		if(!setHeight)
23579			var setHeight = false;
23580		
23581		var objTiles = getTiles();
23582				
23583		var posx = 0;
23584		var maxHeight = 0, totalWidth;
23585		
23586		jQuery.each(objTiles, function(index, objTile){
23587			objTile = jQuery(objTile);
23588			g_functions.placeElement(objTile, posx, 0);
23589			var tileSize = g_functions.getElementSize(objTile);
23590			posx += tileSize.width + g_options.carousel_space_between_tiles;
23591			maxHeight = Math.max(maxHeight, tileSize.height);
23592			if(index == (objTiles.length-1))
23593				totalWidth = tileSize.right;
23594		});
23595		
23596		//set heights and widths
23597		g_objInner.width(totalWidth);
23598				
23599		maxHeight += g_options.carousel_padding * 2;
23600		
23601		if(setHeight === true){
23602			g_objInner.height(maxHeight);
23603			g_objCarouselWrapper.height(maxHeight);
23604		}
23605				
23606		scrollToTile(g_temp.numCurrent, false);
23607
23608		return(totalWidth);
23609	}
23610	
23611	
23612	/**
23613	 * validate that the num not more then num tiles
23614	 */
23615	function validateTileNum(numTile){
23616
23617		if(numTile > (getTiles().length-1))
23618			throw new Error("Wrogn tile number: " + numTile);
23619	}
23620	
23621	
23622	/**
23623	 * add tile to left
23624	 */
23625	function addTiles(numTiles, dir){
23626		
23627		if(dir == "left")
23628			var anchorTile = getFirstTile();
23629		else
23630			var anchorTile = getLastTile();
23631		
23632		var clonesType = (dir == "left")?"prev":"next";
23633		
23634		var arrNewTiles = getTileClones(anchorTile, numTiles, clonesType);
23635				
23636		jQuery.each(arrNewTiles, function(index, objTile){		
23637			
23638			if(dir == "left")
23639				g_objInner.prepend(objTile);
23640			else
23641				g_objInner.append(objTile);
23642			
23643			g_objWrapper.trigger(g_temp.eventSizeChange, objTile);
23644			g_objTileDesign.loadTileImage(objTile);
23645			
23646		});
23647		
23648		
23649	}
23650	
23651	/**
23652	 * remove some tiles
23653	 */
23654	function removeTiles(numTilesToRemove, direction){
23655		
23656		validateTileNum(numTiles);
23657		
23658		var arrTiles = getTiles();
23659		var numTiles = arrTiles.length;
23660		
23661		for(var i=0; i<numTilesToRemove; i++){
23662			
23663			if(direction == "left")
23664				jQuery(arrTiles[i]).remove();
23665			else{
23666				jQuery(arrTiles[numTiles-1-i]).remove();
23667			}
23668		}
23669	}
23670
23671	
23672	/**
23673	 * set inner strip position
23674	 */
23675	function setInnerPos(pos){
23676		var objCss = {
23677				"left":pos+"px"
23678		};
23679		
23680		g_objInner.css(objCss);
23681	}
23682	
23683	
23684	/**
23685	 * scroll to tile by number
23686	 */
23687	function scrollToTile(numTile, isAnimation, isShort){
23688		
23689		if(isAnimation === undefined){
23690			var isAnimation = true;
23691			if(g_objInner.is(":animated"))
23692				return(true);
23693		}
23694				
23695		var objTile = getTile(numTile);
23696		var objSize = g_functions.getElementSize(objTile);
23697		var posScroll = -objSize.left + g_options.carousel_padding;
23698		
23699		var objCss = {
23700				"left":posScroll+"px"
23701		};
23702						
23703		if(isAnimation === true){
23704			
23705			var duration = g_options.carousel_scroll_duration;
23706			var easing = g_options.carousel_scroll_easing;
23707			
23708			if(isShort === true){
23709				duration = g_temp.scrollShortDuration;
23710				easing = g_temp.scrollShortEasing;
23711			}
23712			
23713			g_objInner.stop(true).animate(objCss ,{
23714				duration: duration,
23715				easing: easing,
23716				queue: false,
23717				//progress:function(){t.triggerStripMoveEvent()},
23718				complete: function(){
23719					g_temp.numCurrent = numTile;
23720					
23721					fillSidesWithTiles(true);
23722				}
23723			});					
23724			
23725		}else{
23726			g_temp.numCurrent = numTile;
23727						
23728			g_objInner.css(objCss);
23729		}
23730		
23731	}
23732	
23733	
23734	/**
23735	 * get number of neerest tile
23736	 */
23737	function getNeerestTileNum(){
23738		var innerPos = -getInnerPos();
23739		var numTiles = getNumTilesInSpace(innerPos);
23740		var tile1Pos = g_functions.getElementSize(getTile(numTiles)).left;
23741		var tile2Pos = g_functions.getElementSize(getTile(numTiles+1)).left;
23742				
23743		if(Math.abs(tile1Pos - innerPos) < Math.abs(tile2Pos - innerPos))
23744			return(numTiles);
23745		else			
23746			return(numTiles+1);
23747	}
23748	
23749	
23750	/**
23751	 * get neerest tile to inner position
23752	 */
23753	function scrollToNeerestTile(){
23754		
23755		var tileNum = getNeerestTileNum();
23756		scrollToTile(tileNum, true, true);
23757	}
23758	
23759	
23760	/**
23761	 * fill the sides with tiles till it fil the sideSpace
23762	 */
23763	function fillSidesWithTiles(){
23764				
23765		var spaceLeft = getRemainSpaceLeft();
23766		var spaceRight = getRemainSpaceRight();
23767		
23768		var numItemsLeft = 0, numItemsRight = 0, numItemsRemoveLeft = 0, numItemsRemoveRight = 0;
23769		
23770		//trace("left: " + spaceLeft+ " right: " + spaceRight);
23771		
23772		var numTiles = getNumTiles();
23773		
23774		//add tiles to left
23775		if(spaceLeft > g_temp.spaceActionSize){
23776			numItemsLeft = getNumTilesInSpace(spaceLeft);		
23777			addTiles(numItemsLeft, "left");
23778			
23779			g_temp.numCurrent += numItemsLeft;
23780			
23781		}else if(spaceLeft < -g_temp.spaceActionSize){
23782			var numItemsRemoveLeft = getNumTilesInSpace(Math.abs(spaceLeft));
23783			removeTiles(numItemsRemoveLeft, "left");
23784			g_temp.numCurrent -= numItemsRemoveLeft;
23785		}
23786		
23787		//add tiles to right
23788		if(spaceRight > g_temp.spaceActionSize){
23789			numItemsRight = getNumTilesInSpace(spaceRight);
23790			addTiles(numItemsRight, "right");			
23791		}else if(spaceRight < -g_temp.spaceActionSize){
23792			numItemsRemoveRight = getNumTilesInSpace(Math.abs(spaceRight));
23793			removeTiles(numItemsRemoveRight, "right");			
23794		}
23795		
23796		
23797		//small validation
23798		if(numItemsRemoveRight > numTiles){
23799			
23800			throw new Error("Can't remove more then num tiles");
23801		}
23802			
23803		//trace(numItemsRemoveRight);
23804		//trace("numItems: " + getNumTiles());
23805		
23806		//scroll to tile and position inner object
23807		var isPositioned = false;
23808		if(numItemsLeft || numItemsRight || numItemsRemoveLeft || numItemsRemoveRight){
23809			
23810			/*
23811			debugLine({
23812				numItemsLeft:numItemsLeft,
23813				numItemsRight:numItemsRight,
23814				numItemsRemoveLeft:numItemsRemoveLeft,
23815				numItemsRemoveRight: numItemsRemoveRight
23816			});
23817			*/
23818			//trace("do something");
23819			
23820			positionTiles();			
23821			isPositioned = true
23822		}
23823		
23824		return(isPositioned);
23825	}
23826	
23827	
23828	/**
23829	 * position tiles
23830	 */
23831	function positionElements(isFirstTime){
23832				
23833		//position inner strip
23834		g_functions.placeElement(g_objInner, 0, g_options.carousel_padding);
23835		
23836		//position sides
23837		fillSidesWithTiles();
23838		
23839	}
23840	
23841	
23842	
23843	function __________AUTOPLAY_______(){};
23844
23845	/**
23846	 * start autoplay
23847	 */
23848	this.startAutoplay = function(){
23849		
23850		g_temp.isPlayMode = true;
23851		g_temp.isPaused = false;
23852		
23853		g_objThis.trigger(t.events.START_PLAY);
23854		
23855		if(g_temp.handle)
23856			clearInterval(g_temp.handle);
23857		
23858		g_temp.handle = setInterval(autoplayStep, g_options.carousel_autoplay_timeout);
23859		
23860	}
23861	
23862	
23863	/**
23864	 * unpause autoplay after pause
23865	 */
23866	this.unpauseAutoplay = function(){
23867		
23868		if(g_temp.isPlayMode == false)
23869			return(true);
23870		
23871		if(g_temp.isPaused == false)
23872			return(true);
23873		
23874		t.startAutoplay();
23875	}
23876	
23877	
23878	/**
23879	 * pause the autoplay
23880	 */
23881	this.pauseAutoplay = function(){
23882
23883		if(g_temp.isPlayMode == false)
23884			return(true);
23885		
23886		g_temp.isPaused = true;
23887		
23888		if(g_temp.handle)
23889			clearInterval(g_temp.handle);
23890		
23891		g_objThis.trigger(t.events.PAUSE_PLAY);
23892		
23893	}
23894
23895	
23896	/**
23897	 * stop autoplay
23898	 */
23899	this.stopAutoplay = function(){
23900		
23901		if(g_temp.isPlayMode == false)
23902			return(true);
23903		
23904		g_temp.isPaused = false;
23905		g_temp.isPlayMode = false;
23906		
23907		if(g_temp.handle)
23908			clearInterval(g_temp.handle);
23909		
23910		g_objThis.trigger(t.events.STOP_PLAY);
23911	}
23912	
23913	
23914	/**
23915	 * autoplay step, advance the carousel by 1
23916	 */
23917	function autoplayStep(){
23918		
23919		if(g_options.carousel_autoplay_direction == "left"){
23920			t.scrollRight(1);
23921		}else{
23922			t.scrollLeft(1);
23923		}
23924		
23925	}
23926	
23927	function __________EVENTS_______(){};
23928		
23929	
23930	/**
23931	 * on touch start
23932	 */
23933	function onTouchStart(event){
23934		
23935		if(g_temp.touchActive == true)
23936			return(true);
23937		
23938		g_temp.touchActive = true;
23939		
23940		t.pauseAutoplay();
23941		
23942		g_temp.startTime = jQuery.now();	
23943		g_temp.startMousePos = getMousePos(event);
23944		g_temp.startInnerPos = getInnerPos();
23945		g_temp.lastTime = g_temp.startTime;
23946		g_temp.lastMousePos = g_temp.startMousePos;
23947		
23948		g_functions.storeEventData(event, g_temp.storedEventID);
23949	}
23950
23951	
23952	/**
23953	 * on touch move
23954	 */
23955	function onTouchMove(event){
23956				
23957		if(g_temp.touchActive == false)
23958			return(true);
23959		
23960		g_functions.updateStoredEventData(event, g_temp.storedEventID);
23961		
23962		event.preventDefault();
23963		
23964		var scrollDir = null;
23965		
23966		if(g_options.carousel_vertical_scroll_ondrag == true)
23967			scrollDir = g_functions.handleScrollTop(g_temp.storedEventID);
23968		
23969		if(scrollDir === "vert")
23970			return(true);
23971		
23972		g_temp.lastMousePos = getMousePos(event);
23973		
23974		var diff = g_temp.lastMousePos - g_temp.startMousePos;
23975		var innerPos = g_temp.startInnerPos + diff;
23976		var direction = (diff > 0) ? "prev":"next";
23977		var innerSize = g_functions.getElementSize(g_objInner).width;
23978		
23979		//slow down when off limits
23980		if(innerPos > 0 && direction == "prev"){
23981			innerPos = innerPos / 3;
23982		}
23983		
23984		if(innerPos < -innerSize && direction == "next"){
23985			innerPos = g_temp.startInnerPos + diff / 3;
23986		}
23987		
23988		setInnerPos(innerPos);
23989	}
23990	
23991	
23992	/**
23993	 * on touch end
23994	 * change panes or return to current pane
23995	 */
23996	function onTouchEnd(event){
23997		
23998		if(g_temp.touchActive == false)
23999			return(true);
24000		
24001		//event.preventDefault();
24002		g_temp.touchActive = false;
24003		
24004		scrollToNeerestTile();
24005		
24006		t.unpauseAutoplay();
24007	}
24008	
24009	/**
24010	 * pause the playing
24011	 */
24012	function onMouseEnter(event){
24013		
24014		if(g_options.carousel_autoplay_pause_onhover == false)
24015			return(true);
24016		
24017		if(g_temp.isPlayMode == true && g_temp.isPaused == false)
24018			t.pauseAutoplay();
24019	}
24020	
24021	/**
24022	 * start the playing again
24023	 */
24024	function onMouseLeave(event){
24025		
24026		if(g_options.carousel_autoplay_pause_onhover == false)
24027			return(true);
24028		
24029		t.unpauseAutoplay();
24030	}
24031	
24032	
24033	/**
24034	 * init panel events
24035	 */
24036	function initEvents(){
24037				
24038		g_objTileDesign.initEvents();
24039		
24040		//touch drag events
24041		//slider mouse down - drag start
24042		g_objCarouselWrapper.bind("mousedown touchstart",onTouchStart);
24043		
24044		//on body move
24045		jQuery("body").bind("mousemove touchmove",onTouchMove);
24046		
24047		//on body mouse up - drag end
24048		jQuery(window).add("body").bind("mouseup touchend", onTouchEnd);
24049		
24050		g_objCarouselWrapper.hover(onMouseEnter, onMouseLeave);
24051		
24052	}
24053	
24054	
24055	/**
24056	 * destroy the carousel events
24057	 */
24058	this.destroy = function(){
24059		
24060		if(g_temp.handle)
24061			clearInterval(g_temp.handle);
24062		
24063		g_objThis.off(t.events.START_PLAY);		
24064		g_objThis.off(t.events.STOP_PLAY);		
24065		
24066		//touch drag events
24067		//slider mouse down - drag start
24068		g_objCarouselWrapper.unbind("mousedown");
24069		g_objCarouselWrapper.unbind("touchstart");
24070		
24071		//on body move
24072		jQuery("body").unbind("mousemove");
24073		jQuery("body").unbind("touchmove");
24074		
24075		//on body mouse up - drag end
24076		jQuery(window).add("body").unbind("mouseup").unbind("touchend");
24077		
24078		g_objCarouselWrapper.off("mouseenter").off("mouseleave");
24079		
24080		g_objTileDesign.destroy();
24081	}
24082
24083	
24084	/**
24085	 * init function for avia controls
24086	 */
24087	this.init = function(gallery, customOptions, width){
24088		if(width)
24089			this.setMaxWidth(width);
24090		
24091		init(gallery, customOptions);
24092	}
24093
24094	
24095	/**
24096	 * set the width
24097	 */
24098	this.setMaxWidth = function(width){
24099		
24100		g_temp.carouselMaxWidth = width;
24101	}
24102	
24103	
24104	/**
24105	 * set html
24106	 */
24107	this.setHtml = function(objParent){
24108		setHtml(objParent);
24109	}
24110	
24111	/**
24112	 * get the carousel element
24113	 */
24114	this.getElement = function(){
24115		return g_objCarouselWrapper;
24116	}
24117	
24118	/**
24119	 * get tile design object
24120	 */
24121	this.getObjTileDesign = function(){
24122		return(g_objTileDesign);
24123	}
24124	
24125	
24126	/**
24127	 * get estimated height
24128	 */
24129	this.getEstimatedHeight = function(){
24130		var height = g_options.tile_height + g_options.carousel_padding * 2;
24131		return(height);
24132	}
24133	
24134	
24135	/**
24136	 * set html and properties
24137	 */	
24138	this.run = function(){
24139		run();
24140	}
24141	
24142	
24143	/**
24144	 * scroll to right
24145	 */
24146	this.scrollRight = function(tilesToScroll){
24147		
24148		if(!tilesToScroll || typeof tilesToScroll == "object")
24149			var tilesToScroll = g_options.carousel_navigation_numtiles;
24150
24151		var numTilesInCarousel = getNumTilesInCarousel();
24152		if(tilesToScroll > numTilesInCarousel)
24153			tilesToScroll = numTilesInCarousel;
24154		
24155		var numPrev = g_temp.numCurrent - tilesToScroll;
24156		if(numPrev <=0)
24157			numPrev = 0;
24158		
24159		scrollToTile(numPrev);
24160	}
24161	
24162	
24163	/**
24164	 * scroll to left
24165	 */
24166	this.scrollLeft = function(tilesToScroll){
24167				
24168		if(!tilesToScroll || typeof tilesToScroll == "object")
24169			var tilesToScroll = g_options.carousel_navigation_numtiles;
24170		
24171		var numTilesInCarousel = getNumTilesInCarousel();
24172		if(tilesToScroll > numTilesInCarousel)
24173			tilesToScroll = numTilesInCarousel;
24174		
24175		var numTiles = getNumTiles();
24176		
24177		var numNext = g_temp.numCurrent + tilesToScroll;
24178		if(numNext >= numTiles)
24179			numNext = numTiles-1;
24180	
24181		scrollToTile(numNext);
24182	}
24183	
24184	/**
24185	 * set scroll left button
24186	 */
24187	this.setScrollLeftButton = function(objButton){
24188		g_functions.setButtonMobileReady(objButton);
24189		g_functions.setButtonOnClick(objButton, t.scrollLeft);
24190	}
24191	
24192	
24193	/**
24194	 * set scroll right button
24195	 */
24196	this.setScrollRightButton = function(objButton){
24197		g_functions.setButtonMobileReady(objButton);
24198		g_functions.setButtonOnClick(objButton, t.scrollRight);
24199	}
24200	
24201	
24202	/**
24203	 * set scroll right button
24204	 */
24205	this.setPlayPauseButton = function(objButton){
24206		g_functions.setButtonMobileReady(objButton);
24207		
24208		if(g_temp.isPlayMode == true && g_temp.isPaused == false){
24209			objButton.addClass("ug-pause-icon");			
24210		}
24211		
24212		g_objThis.on(t.events.START_PLAY, function(){
24213			objButton.addClass("ug-pause-icon");
24214		});
24215		
24216		g_objThis.on(t.events.STOP_PLAY, function(){
24217			objButton.removeClass("ug-pause-icon");
24218		});
24219		
24220		g_functions.setButtonOnClick(objButton, function(){
24221				
24222				if(g_temp.isPlayMode == false || g_temp.isPaused == true)					
24223					t.startAutoplay();
24224				else
24225					t.stopAutoplay();
24226				
24227		});
24228	}
24229	
24230	
24231	/**
24232	 * return if passed some significant movement
24233	 */
24234	function isApproveTileClick(){
24235		
24236		var passedTime = g_temp.lastTime - g_temp.startTime;		
24237		var passedDistanceAbs = Math.abs(g_temp.lastMousePos - g_temp.startMousePos);
24238		
24239		if(passedTime > 300)
24240			return(false);
24241		
24242		if(passedDistanceAbs > 30)
24243			return(false);
24244		
24245		return(true);
24246	}
24247	
24248	
24249}
24250
24251
24252
24253/**
24254 tabs panel class addon to unite gallery
24255 */
24256function UGTabs(){
24257	
24258	var t = this, g_objThis = jQuery(this),g_objGallery;
24259	var g_gallery = new UniteGalleryMain(), g_functions = new UGFunctions();
24260	var g_objTabs, g_objSelect;
24261	
24262
24263	var g_options = {
24264		tabs_type:"tabs",					//tabs type: tabs, select
24265		tabs_container: "#ug_tabs",			//tabs container
24266		tabs_class_selected: "ug-tab-selected"
24267	};
24268	
24269	this.events = {
24270		
24271	};
24272	
24273	
24274	/**
24275	 * init tabs function
24276	 */
24277	function initTabs(gallery, customOptions){
24278		g_gallery = gallery;
24279		
24280		g_objGallery = jQuery(g_gallery);
24281		
24282		g_options = jQuery.extend(g_options, customOptions);
24283		
24284		if(g_options.tabs_type == "select")
24285			g_objSelect = jQuery(g_options.tabs_container);
24286		else
24287			g_objTabs = jQuery(g_options.tabs_container + " .ug-tab");
24288		
24289	}
24290	
24291	
24292	
24293	/**
24294	 * run the tabs
24295	 */
24296	function runTabs(){
24297				
24298		initEvents();
24299	}
24300	
24301	
24302	/**
24303	 * request new gallery items
24304	 */
24305	function requestGalleryItems(catid){
24306		
24307		g_gallery.requestNewItems(catid);
24308		
24309	}
24310	
24311	
24312	/**
24313	 * on tab click
24314	 */
24315	function onTabClick(){
24316		
24317		var classSelected = g_options.tabs_class_selected;
24318		
24319		var objTab = jQuery(this);
24320		if(objTab.hasClass(classSelected))
24321			return(true);
24322		
24323		g_objTabs.not(objTab).removeClass(classSelected);
24324		objTab.addClass(classSelected);
24325		
24326		var catID = objTab.data("catid");
24327		if(!catID)
24328			return(true);
24329		
24330		requestGalleryItems(catID);
24331		
24332	}
24333	
24334	
24335	/**
24336	 * on select change
24337	 */
24338	function onSelectChange(){
24339		var objSelect = jQuery(this);
24340		var catID = objSelect.val();
24341		
24342		if(!catID)
24343			return(true);
24344		
24345		requestGalleryItems(catID);
24346	}
24347	
24348	
24349	/**
24350	 * init tabs events
24351	 */
24352	function initEvents(){
24353		
24354		if(g_options.tabs_type == "select")
24355			g_objSelect.change(onSelectChange);
24356		else
24357			g_objTabs.click(onTabClick);
24358	}
24359	
24360	/**
24361	 * destroy
24362	 */
24363	this.destroy = function(){
24364		
24365		if(g_objSelect)
24366			g_objSelect.off("change");
24367		
24368		if(g_objTabs)
24369			g_objTabs.off("click");
24370	}
24371	
24372	
24373	/**
24374	 * outer init function, move to inner init
24375	 */
24376	this.init = function(gallery, customOptions){
24377		initTabs(gallery, customOptions);
24378	}
24379	
24380	
24381	/**
24382	 * run the tabs
24383	 */
24384	this.run = function(){
24385		
24386		runTabs();
24387	}
24388	
24389	
24390}
24391
24392
24393/**
24394 * API Class
24395 * addon to Unite gallery
24396 */
24397function UG_API(gallery){
24398	
24399	var t = this, g_objThis = jQuery(t);
24400	var g_gallery = new UniteGalleryMain(), g_objGallery;
24401	var g_arrEvents = [];
24402	
24403	g_gallery = gallery;
24404	g_objGallery = jQuery(gallery);
24405	
24406	
24407	this.events = {
24408			API_INIT_FUNCTIONS:"api_init",
24409			API_ON_EVENT:"api_on_event"
24410	}
24411	
24412	
24413	/**
24414	 * get item data for output
24415	 */
24416	function convertItemDataForOutput(item){
24417		
24418		var output = {
24419				index: item.index,
24420				title: item.title,
24421				description: item.description,
24422				urlImage: item.urlImage,
24423				urlThumb: item.urlThumb
24424			};
24425			
24426			//add aditional variables to the output
24427			var addData = item.objThumbImage.data();
24428			
24429			for(var key in addData){
24430				switch(key){
24431					case "image":
24432					case "description":
24433						continue;
24434					break;
24435				}
24436				output[key] = addData[key];
24437			}
24438			
24439			return(output);
24440	}
24441	
24442	
24443	/**
24444	 * event handling function
24445	 */
24446	this.on = function(event, handlerFunction, notCache){
24447		
24448		//remember cache
24449		if(notCache !== true){
24450			g_arrEvents.push({event:event,func:handlerFunction});
24451		}
24452		
24453		switch(event){
24454			case "item_change":
24455				
24456				g_objGallery.on(g_gallery.events.ITEM_CHANGE, function(){
24457						var currentItem = g_gallery.getSelectedItem();
24458						var output = convertItemDataForOutput(currentItem);
24459						handlerFunction(output.index, output);
24460				});
24461				
24462			break;
24463			case "resize":
24464				g_objGallery.on(g_gallery.events.SIZE_CHANGE, handlerFunction);
24465			break;
24466			case "enter_fullscreen":
24467				g_objGallery.on(g_gallery.events.ENTER_FULLSCREEN, handlerFunction);				
24468			break;
24469			case "exit_fullscreen":
24470				g_objGallery.on(g_gallery.events.EXIT_FULLSCREEN, handlerFunction);				
24471			break;
24472			case "play":
24473				g_objGallery.on(g_gallery.events.START_PLAY, handlerFunction);				
24474			break;
24475			case "stop":
24476				g_objGallery.on(g_gallery.events.STOP_PLAY, handlerFunction);				
24477			break;
24478			case "pause":
24479				g_objGallery.on(g_gallery.events.PAUSE_PLAYING, handlerFunction);				
24480			break;
24481			case "continue":
24482				g_objGallery.on(g_gallery.events.CONTINUE_PLAYING, handlerFunction);
24483			break;
24484			case "open_lightbox":
24485				g_objGallery.on(g_gallery.events.OPEN_LIGHTBOX, handlerFunction);
24486			break;
24487			case "close_lightbox":
24488				g_objGallery.on(g_gallery.events.CLOSE_LIGHTBOX, handlerFunction);
24489			break;
24490			default:
24491				if(console)
24492					console.log("wrong api event: " + event);
24493			break;
24494		}
24495		
24496		g_objGallery.trigger(t.events.API_ON_EVENT, [event, handlerFunction]);
24497	}
24498	
24499	
24500	/**
24501	 * start playing 
24502	 */
24503	this.play = function(){		
24504		g_gallery.startPlayMode();		
24505	}
24506	
24507	
24508	/**
24509	 * stop playing
24510	 */
24511	this.stop = function(){
24512		g_gallery.stopPlayMode();
24513	}
24514	
24515	
24516	/**
24517	 * toggle playing
24518	 */
24519	this.togglePlay = function(){
24520		g_gallery.togglePlayMode();
24521	}
24522	
24523	
24524	/**
24525	 * enter fullscreen
24526	 */
24527	this.enterFullscreen = function(){
24528		g_gallery.toFullScreen();
24529	}
24530	
24531	/**
24532	 * exit fullscreen
24533	 */
24534	this.exitFullscreen = function(){
24535		g_gallery.exitFullScreen();
24536	}
24537	
24538	/**
24539	 * toggle fullscreen
24540	 */
24541	this.toggleFullscreen = function(){
24542		
24543		g_gallery.toggleFullscreen();		
24544	}
24545	
24546	
24547	/**
24548	 * reset zoom
24549	 */
24550	this.resetZoom = function(){
24551		var objSlider = g_gallery.getObjSlider();
24552		if(!objSlider)
24553			return(false);
24554		
24555		objSlider.zoomBack();
24556	}
24557	
24558	
24559	/**
24560	 * zoom in
24561	 */
24562	this.zoomIn = function(){
24563		
24564		var objSlider = g_gallery.getObjSlider();
24565		if(!objSlider)
24566			return(false);
24567		
24568		objSlider.zoomIn();		
24569	}
24570
24571	/**
24572	 * zoom in
24573	 */
24574	this.zoomOut = function(){
24575		
24576		var objSlider = g_gallery.getObjSlider();
24577		if(!objSlider)
24578			return(false);
24579		
24580		objSlider.zoomOut();		
24581	}
24582	
24583	/**
24584	 * next item
24585	 */
24586	this.nextItem = function(){
24587		g_gallery.nextItem();
24588	}
24589	
24590	
24591	/**
24592	 * prev item
24593	 */
24594	this.prevItem = function(){
24595		g_gallery.prevItem();
24596	}
24597	
24598	/**
24599	 * go to some item by index (0-numItems)
24600	 */
24601	this.selectItem = function(numItem){
24602		
24603		g_gallery.selectItem(numItem);
24604	
24605	}
24606	
24607	
24608	/**
24609	 * resize the gallery to some width (height).
24610	 */
24611	this.resize = function(width, height){
24612		
24613		if(height)
24614			g_gallery.resize(width, height);
24615		else
24616			g_gallery.resize(width);
24617	}
24618	
24619	
24620	/**
24621	 * get some item by index
24622	 */
24623	this.getItem = function(numItem){
24624		
24625		var data = g_gallery.getItem(numItem);
24626		var output = convertItemDataForOutput(data);
24627		
24628		return(output);
24629	}
24630	
24631	
24632	/**
24633	 * get number of items in the gallery
24634	 */
24635	this.getNumItems = function(){
24636		var numItems = g_gallery.getNumItems();
24637		return(numItems);
24638	}
24639	
24640	/**
24641	 * refresh gallery with another options
24642	 */
24643	this.reloadGallery = function(customOptions){
24644		if(!customOptions)
24645			var customOptions = {};
24646		
24647		g_gallery.run(null, customOptions);
24648		
24649		//restore events:
24650		g_arrEvents.map(function(obj){
24651			t.on(obj.event,obj.func,true);
24652		});
24653		
24654	}
24655	
24656	
24657	/**
24658	 * destroy the gallery
24659	 */
24660	this.destroy = function(){
24661		g_gallery.destroy();
24662	}
24663	
24664	//trigger api on init event
24665	g_objGallery.trigger(t.events.API_INIT_FUNCTIONS, t);
24666	
24667}
24668

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.