﻿
//AX'd home brew slider!
/*	USAGE:
 *	...pretty straight-forward...
 *		i.e. var slider = new PanelSlider(jQuery);
 *			argument[0] ensures $ === jQuery so other libs can't interfere
 *	
 *	Initialize by calling SetSlider(obj[] oPanelArray, int panelsPerPage, {string[]} oControls)
 *		i.e. slider.SetSlider($('#table td'), 5, {Previous : ['.controls'], Next : ['#backButton']});
 *		
 *		oControls NOTE: Does not yet sub-parse obj[] passed in; i.e. $('.controls .prev a')
 *						Only handles control assignment 1 to 1.
 *		
 *		Container NOTE: The distance of the swing is determined by multiplying the absolute
 *						width of the first panel (width + l/r margin + l/r padding + l/r border)
 *						by the number of panels per "page". So, make sure the container width
 *						is a multiple of that element.
*/
function PanelSlider($, undefined)
{
	var transitioning = false;
	var $slider = null;
	var pub =
	{
		TargetId: ""
		, Index: 0
		, Panels:
		{ Items: []
			, PerPage: 0
			, Width: 0
		}
		, Pages: 0
		, SwingDistance: 0
		, Controls:
		{ Previous: []
			, Next: []
		}
		, SlidePrev: function ()
		{
			if (transitioning) { return false; }
			if (pub.Index > 0)
			{
				SetPanelDisplay(((pub.Index - 1) * pub.Panels.PerPage), ((pub.Index + 1) * pub.Panels.PerPage));
				$slider.css({ left: -pub.SwingDistance });

				pub.Index--;

				transitioning = true;
				SlideElement(pub.TargetId, 0, function ()
				{
					//do we disable prev controls?
					if (pub.Index <= 0) { DisableControl("previous"); }

					//do we enable next controls?
					if (pub.Controls.Next[0].disabled && pub.Index < pub.Pages) { EnableControl("next"); }

					//reset the panel position to 0?
					ResetPosition();
					transitioning = false;
				});
			}
		}
		, SlideNext: function ()
		{
			if (transitioning) { return false; }
			if (pub.Index < pub.Pages - 1)
			{
				SetPanelDisplay((pub.Index * pub.Panels.PerPage), ((pub.Index + 2) * pub.Panels.PerPage));

				pub.Index++;

				transitioning = true;
				SlideElement(pub.TargetId, -pub.SwingDistance, function ()
				{
					if (pub.Index + 1 == pub.Pages) { DisableControl("next"); }
					if (pub.Controls.Previous[0].disabled && pub.Index > 0) { EnableControl("previous"); }
					ResetPosition();
					transitioning = false;
				});
			}
		}
		, SetSlider: function (targetID, oPanelArray, panelsPerPage, oControls)
		{
			if (oPanelArray.length > 0 && document.getElementById(targetID))
			{
				//populate public variables
				pub.TargetId = targetID;
				pub.Panels.Items = oPanelArray;
				pub.Panels.PerPage = panelsPerPage;

				$slider = $('#' + pub.TargetId);

				//calculate panel properties based on the first element. 
				//Obviously, all panels in the slider need to have the same basic style...
				$panel = $(oPanelArray[0]);
				pub.Panels.Width = ValueToInt($panel.width());
				pub.Panels.Width += ValueToInt($panel.css("padding-left"), 10) + ValueToInt($panel.css("padding-right"), 10); //Total Padding Width
				pub.Panels.Width += ValueToInt($panel.css("margin-left"), 10) + ValueToInt($panel.css("margin-right"), 10); //Total Margin Width
				pub.Panels.Width += ValueToInt($panel.css("borderLeftWidth"), 10) + ValueToInt($panel.css("borderRightWidth"), 10); //Total Border Width
				pub.SwingDistance = pub.Panels.Width * pub.Panels.PerPage;

				//set pages
				if (pub.Panels.Items.length <= pub.Panels.PerPage)
				{
					pub.Pages = 1;
				}
				else
				{
					pub.Pages = (Math.ceil(pub.Panels.Items.length / pub.Panels.PerPage))
				}

				SetPanelDisplay(0, pub.Panels.PerPage * 2);

				//set slider container properties; position: absolute; width: pages * slide distance
				$slider.css
				({
					'position': "absolute"
					, ' width': (pub.Pages * pub.SwingDistance)
				});


				//set controllers
				for (var i = oControls.Previous.length - 1; i >= 0; i--)
				{
					$(oControls.Previous[i]).click(this.SlidePrev);
					pub.Controls.Previous.push(($(oControls.Previous[i]))[0]);
				}
				DisableControl("previous");


				for (var i = oControls.Next.length - 1; i >= 0; i--)
				{
					$(oControls.Next[i]).click(this.SlideNext);
					pub.Controls.Next.push(($(oControls.Next[i])));
				}
				if(pub.Pages <= 1)
				{
					DisableControl("next");
				}
			}
		}

	}

	//do the slide
	function SlideElement(targetId, distance, fCallback)
	{
		$slider.animate({ left: distance }, "slow", "swing", fCallback);
	}

	function SetPanelDisplay(startIndex, endIndex)
	{
		//if (startIndex < 0) { startIndex = 0; }
		//if (endIndex >= pub.Panels.Items.length) { endIndex = pub.Panels.Items.length; }
		for (var i = 0; i < pub.Panels.Items.length; i++)
		{
			pub.Panels.Items[i].style.display = (i >= startIndex && i < endIndex)
				? "" //block
				: "none"
			;
		}
	}

	function ResetPosition()
	{
		SetPanelDisplay((pub.Index * pub.Panels.PerPage), ((pub.Index + 1) * pub.Panels.PerPage))
		$slider.css({left: 0});
	}

	//loops through pub.Controls to disable the [] specified. This involves adding the
	//"disabled" class to the element and flagging the object's disabled property.
	//controlType = "previous" or "next"; 
	function DisableControl(controlType)
	{
		var controls = (controlType === "previous")
						? pub.Controls.Previous
						: pub.Controls.Next
					;

		for (var i = controls.length - 1; i >= 0; i--)
		{
			if (!$(controls[i]).hasClass("disabled"))
			{
				$(controls[i]).addClass("disabled");
			}
			controls[i].disabled = true;
		}
	}

	//loops through pub.Controls to enable the [] specified, remong all "disabled" flags
	//Set by DisableControl().
	//controlType = "previous" or "next"; 
	function EnableControl(controlType)
	{
		var controls = (controlType === "previous")
						? pub.Controls.Previous
						: pub.Controls.Next
					;

		for (var i = controls.length - 1; i >= 0; i--)
		{
			$(controls[i]).removeClass("disabled");
			controls[i].disabled = false;
		}
	}

	return pub;
}


function CollectionDisplay($, undefined)
{
	var $largeImage = "";
	var duration = "";
	var pub =
	{
		LargeImage: null
		, Thumbnails: []
		, SwapImage: function ()
		{
			var control = this;
			if (Contains(pub.LargeImage.src, control.getAttribute("Value"))) { return; }

			$(pub.LargeImage).fadeOut(duration, function ()
			{
				pub.LargeImage.src = control.getAttribute("Value");
				$(pub.LargeImage).fadeIn(duration);
			});
		}
		, SetDisplay: function (thumbContainerId, transitionSpeed)
		{
			duration = transitionSpeed;

			pub.Thumbnails = $('#' + thumbContainerId + " a");

			if (pub.Thumbnails.length > 0)
			{
				for (var i = 0; i < pub.Thumbnails.length; i++)
				{
					pub.Thumbnails[i].onclick = pub.SwapImage;
				}

				$largeImage = $('#' + pub.Thumbnails[0].getAttribute("TargetId"));
				if (typeof ($largeImage) == 'object' && ($largeImage).length > 0)
				{
					$largeImage = null;
					$largeImage = $('#' + pub.Thumbnails[0].getAttribute("TargetId"))[0];
				}
				pub.LargeImage = $largeImage;
			}
		}
	}
	return pub;
}


function StyleGuideCaptions($, undefined)
{
	var duration = "";
	var controlClass = "";
	var captionClass = "";
	var scrollHeight = "";
	pub =
	{
		Controls: []
		, ShowCaption: function ()
		{
			$(captionClass, this).stop().animate({ top: '-' + scrollHeight + 'px' }, { queue: false, duration: duration });
			//$(captionClass, this).slideUp(duration)
		}
		, HideCaption: function ()
		{
			$(captionClass, this).stop().animate({ top: '0px' }, { queue: false, duration: duration });
			//$(captionClass, this).slideDown(duration)
		}
		, SetControls: function (containerId, controlClassName, captionClassName, transitionSpeed)
		{
			if (!Contains(controlClassName, ".")) { controlClassName = "." + controlClassName; }
			pub.Controls = $(controlClassName);

			if (pub.Controls.length > 0)
			{
				if (!transitionSpeed) { transitionSpeed = "fast"; }

				if (!captionClassName) { captionClassName = "span"; }
				else if (!Contains(captionClassName, ".")) { captionClassName = "." + captionClassName; }

				for (var i = 0; i < pub.Controls.length; i++)
				{
					pub.Controls[i].onmouseover = pub.ShowCaption;
					pub.Controls[i].onmouseout = pub.HideCaption;
				}

				$caption = $($(captionClassName, pub.Controls[0])[0]);
				scrollHeight = ValueToInt($caption.height());
				scrollHeight += ValueToInt($caption.css("padding-top"), 10) + ValueToInt($caption.css("padding-bottom"), 10); //Total Padding Height
				scrollHeight += ValueToInt($caption.css("margin-top"), 10) + ValueToInt($caption.css("margin-bottom"), 10); //Total Margin Height
				scrollHeight += ValueToInt($caption.css("borderTopWidth"), 10) + ValueToInt($caption.css("borderBottomWidth"), 10); //Total Border Width

				controlClass = controlClassName;
				captionClass = captionClassName;
				duration = transitionSpeed;
			}
		}
	};

	return pub;
}
