/*------------------------------------------------------------------------------

	Filename             thunder.client.js
	Detail               Standard process library
	Author:              thunder::tech inc.
	License:             CLIENT is defined as the owner of online property from which this file resides or this code is referenced in.
						 ADDITIONAL PARTY is defined as anyone other than thunder::tech or CLIENT.
						 No right is granted to CLIENT or ADDITIONAL PARTY to sell, distribute, modify or otherwise transfer the following source code without explicit written permission by thunder::tech.

------------------------------------------------------------------------------*/

var thunder = { client: { utils: {}, modify: {}, checks: {} } };

/*------------------------------------------------------------------------------

	thunder.client.modify
	Create dynamic interactivity by modifying existing markup

	Each method is documented using the following terms.
	hook: JQuery/CSS hook that activates the functionality on an element
	output: The change that the functionality results in; almost always in the form of a JQuery/CSS hook change

------------------------------------------------------------------------------*/

	// method thunder.client.modify.selfLabelFields()
	// hook: .thunder-self-labeled
	// uses existing value attribute as label
	// sets thunder.markup:label attribute
	// output: toggling .thunder-label-cleared
	thunder.client.modify.selfLabelFields = function()
	{
		// Auto-label search field
		$(".thunder-self-labeled").each(function(i)
		{
			this.setAttribute('thunder.markup:label',this.value)
		}).focus(function()
		{
			if(this.value==this.getAttribute('thunder.markup:label'))
			{
				this.value='';
				$(this).addClass('thunder-label-cleared');
			}
		}).blur(function()
		{
			if(this.value=='')
			{
				this.value=this.getAttribute('thunder.markup:label');
				$(this).removeClass('thunder-label-cleared');
			}
		});
	};

	// method thunder.client.modify.treeMenu()
	// parameters
	// - treeMenuExtensions:Object - an array of extensions
	// hooks: .thunder-menu., .menu-item
	// output: toggling .item-on
	thunder.client.modify.treeMenu = function(treeMenuExtensions)
	{
		$('.thunder-menu').mouseenter(function()
		{
			if(treeMenuExtensions) for(var treeMenuMode in treeMenuExtensions) if(treeMenuExtensions[treeMenuMode].enter) treeMenuExtensions[treeMenuMode].enter(this);
			return true;
		}).mouseleave(function()
		{
			if(treeMenuExtensions) for(var treeMenuMode in treeMenuExtensions) if(treeMenuExtensions[treeMenuMode].leave) treeMenuExtensions[treeMenuMode].leave(this);
			return true;
		}).find('.menu-item').not('.item-separator').mouseenter(function()
		{
			$(this).addClass('item-on');
			if(treeMenuExtensions) for(var treeMenuMode in treeMenuExtensions) if(treeMenuExtensions[treeMenuMode].over) treeMenuExtensions[treeMenuMode].over(this);
			return true;
		}).mouseleave(function()
		{
			$(this).removeClass('item-on');
			if(treeMenuExtensions) for(var treeMenuMode in treeMenuExtensions) if(treeMenuExtensions[treeMenuMode].out) treeMenuExtensions[treeMenuMode].out(this);
			return true;
		}).each(function()
		{
			if(treeMenuExtensions) for(var treeMenuMode in treeMenuExtensions) if(treeMenuExtensions[treeMenuMode].init) treeMenuExtensions[treeMenuMode].init(this);
			return true;
		});
	};
	
	// method thunder.client.modify.scrollFeature()
	// parameters
	// - scrollImageWidth
	// - scrollImageTime (ms)
	// - scrollImageAnimationTime (ms)
	// hook: .thunder-scroll-feature [total object], .thunder-scroll-viewport [overflow container], .thunder-scroll-left [click], .thunder-scroll-right [click]
	// output: controlling style.left
	// returns: object with control functions
	thunder.client.modify.scrollFeature = function(scrollImageWidth, scrollImageTime, scrollImageAnimationTime, scrollCallback)
	{
		var _feature = {};
		_feature.counting = false;
		_feature.index = -1;
		_feature.direction = 1;
		_feature.precommence = function()
		{
			_feature.timeout = setTimeout(_feature.change, scrollImageTime);
			_feature.counting = true;
		}
		_feature.commence = function()
		{
			if(_feature.counting==true)
			{
				_feature.counting = false;
				clearTimeout(_feature.timeout);
			}
			_feature.change();
		}
		_feature.next = function() { _feature.direction = 1; _feature.commence(); }
		_feature.previous = function() { _feature.direction = -1; _feature.commence(); }
		_feature.change = function()
		{
			_feature.previndex = _feature.index;
			_feature.index += _feature.direction;
			if(_feature.index >= _feature.images.length) _feature.index = 0;
			if(_feature.index < 0) _feature.index = _feature.images.length - 1;
			_feature.scrollNow();
		}
		_feature.changeTo = function(newIndex)
		{
			clearTimeout(_feature.timeout);
			_feature.previndex = _feature.index;
			_feature.index = newIndex;
			if(_feature.index >= _feature.images.length) _feature.index = 0;
			if(_feature.index < 0) _feature.index = _feature.images.length - 1;
			if(_feature.index != _feature.previndex) _feature.scrollNow();
		}
		_feature.scrollNow = function()
		{
			if(scrollCallback) scrollCallback(_feature);
			if(_feature.previndex>=0)
			{
				if(_feature.direction>0)
					$(_feature.images[_feature.previndex]).animate({'left': 0 - scrollImageWidth}, {duration: scrollImageAnimationTime, queue: false});
				else
					$(_feature.images[_feature.previndex]).animate({'left': scrollImageWidth}, {duration: scrollImageAnimationTime, queue: false});
			}
			if(_feature.index>=0)
			{
				if(_feature.direction>0)
					_feature.images[_feature.index].style.left = scrollImageWidth + 'px';
				else
					_feature.images[_feature.index].style.left = '-' + scrollImageWidth + 'px';
				$(_feature.images[_feature.index]).animate({'left': 0}, {duration: scrollImageAnimationTime * .95, queue: false});
			}
			_feature.precommence();
		}
		_feature.images = $('.thunder-scroll-feature').children('.thunder-scroll-viewport').find('img');
		_feature.images.css('left', '-'+scrollImageWidth+'px');
		if(_feature.images.length>0) { _feature.commence(); _feature.images[0].style.left = 0; }
		$('.thunder-scroll-feature').children('.thunder-scroll-left').click(_feature.previous);
		$('.thunder-scroll-feature').children('.thunder-scroll-right').click(_feature.next);
		return _feature;
	};

	// method thunder.client.modify.tabSet()
	// hooks: .thunder-tab, .thunder-tab-window
	// correlator: (tab) thunder.markup:item="css-hook" e.g. #this-tab-window or .these-tab-windows
	// output: toggling .thunder-tab-on, .thunder-tab-window-on
	// parameters: c:Function; callback(s) where s:String is thunder.markup:item
	thunder.client.modify.tabSet = function(c)
	{
		$('.thunder-tab').click(function()
		{
			$('.thunder-tab').removeClass('thunder-tab-on');
			$('.thunder-tab-window').removeClass('thunder-tab-window-on');
			$(this).addClass('thunder-tab-on');
			$(this.getAttribute('thunder.markup:item')).addClass('thunder-tab-window-on');
			if(c) c(this.getAttribute('thunder.markup:item'));
		});
	}

	// method thunder.client.modify.requireFields()
	// hooks: .thunder-required, .thunder-requiree
	// output: modifies the requiree's disabled property
	//			adds .thunder-requiree-met, .thunder-required-met when requirements met
	thunder.client.modify.requireFields = function()
	{
		var requireChecker = function()
		{
			var disableRequirees = false;
			$('.thunder-required').each(function()
			{
				if(thunder.client.checks.selfLabelFilled(this)==false)
				{
					disableRequirees = true;
					$(this).removeClass('thunder-required-met');
				}
				else
				{
					$(this).addClass('thunder-required-met');
				}
			});
			$('.thunder-requiree').each(function()
			{
				if(disableRequirees==true)
				{
					$(this).removeClass('thunder-requiree-met');
				}
				else
				{
					$(this).addClass('thunder-requiree-met');
				}
				this.disabled = disableRequirees;
			});
		};
		requireChecker();
		$('.thunder-required').change(requireChecker);
		$('.thunder-required').keypress(requireChecker);
	};

/*------------------------------------------------------------------------------

	thunder.client.utils
	Simple utility functions

------------------------------------------------------------------------------*/

	// deselects text; from www.kirupa.com/forum/showthread.php?t=348048
	thunder.client.utils.deselect = function()
	{
		if(document.selection && document.selection.empty)
		{
			document.selection.empty();
		}
		else if(window.getSelection)
		{
			sel=window.getSelection();
			if(sel && sel.removeAllRanges) sel.removeAllRanges();
		}
	}


/*------------------------------------------------------------------------------

	thunder.client.checks
	Boolean conditional functions

------------------------------------------------------------------------------*/

	// method thunder.client.checks.selfLabelFilled(field):Boolean
	// works on both self-labeled via this script and non-self-labeled fields
	// returns: true if filled, false if empty
	thunder.client.checks.selfLabelFilled = function(field)
	{
		if(field.value===''||field.value==field.getAttribute('thunder.markup:label'))
		{
			return false;
		}
		else
		{
			return true;
		}
	}

