var CORE = function () {
	return {};
}();

CORE.Utils = function () {
	var that = arguments.callee.prototype;
	that.getJson = function (settings, callback) {
		if (arguments[0].constructor != Object) settings = {};
		if (!settings.data) settings.data = '';
		if (!settings.url) return alert('No url provided.');
		if (!settings.dataType) settings.dataType = 'json';
		//try {
			$.ajax({
				type: 'POST',
				url: settings.url,
				data: 'ajax=1&' + settings.data,
				dataType: settings.dataType,
				timeout: 15 * 1000, // quit trying after 5 secs
				success: function (data) {
					if (callback) callback(data);
				},
				error: function (xhr, status, error) {
					if (settings.error) {
						settings.error();
					} else {
						alert(status);
					}
				},
				complete: function () {
					if (settings.complete) settings.complete();
				}
			});
		//} catch (e) {
			// most likely a timeout issue
		//}
	};
	that.getCookie = function (name) {
		var i,x,y,ARRcookies=document.cookie.split(";");
		for (i=0;i<ARRcookies.length;i++) {
			x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
			y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
			x=x.replace(/^\s+|\s+$/g,"");
			if (x==name) return unescape(y);
		}
	};
	that.setCookie = function (name, value, exdays) {
		var exdate = new Date();
		exdate.setDate(exdate.getDate() + exdays);
		var val = escape(value) + ((exdays==null) ? "" : "; expires=" + exdate.toUTCString());
		document.cookie = name + "=" + val;
	}
	that.inArray = function (valOrArray, arr) {
		var i = arr.length;
		while (i--) if (arr[i] == valOrArray) return true;
		return false;
	};
	that.arrayIntersect = function (a1, a2) {
		var res = [];
		var i = a1.length;
		var j;
		while (i--) {
			j = a2.length;
			while (j--) {
				if (a1[i] == a2[j]) res.push(a1[i]);
			}
		}
		return res;
	};
	that.arrayDiff = function (a1, a2) {
		var res = [];
		var i = a1.length;
		var j, isMatch;
		while (i--) {
			j = a2.length;
			isMatch = false;
			while (j--) if (a1[i] == a2[j]) isMatch = true;
			if (!isMatch) res.push(a1[i]);
		}
		return res.reverse();
	};
	that.fixButton = function (isValid, button) {
		var isDisable = true;
		var opacity = 0.7;
		if (isValid) {
			isDisable = false;
			opacity = 1;
		}
		button.attr('disabled', isDisable).css('opacity', opacity);
	};
};

CORE.Slider = function () {
	var that = this;
	var opts = (arguments[0].constructor == Object) ? arguments[0] : {};
	if (!opts.selector) opts.selector = arguments[0];
	opts.stripeSelector = '.content';
	if (!opts.delay) opts.delay = 11; // delay between rotations
	that.isPlayMode = (!opts.isPlayMode) ? false : true;
	var startX = null;
	var posX = null;
	var objW = null; // total width of all items put in one line
	var shiftVal = null; // width of individual item
	var spacing = 0; // spacing between items
	var maxW = null; // max width of visible items
	var totalItems = 0;
	var currentPage = 0;
	var timer = null;
	function init() {
		var box = $(opts.selector).css('overflow', 'visible');
		if (box.length > 0) {
			box.wrapInner('<div class="capsule"><div class="' + opts.stripeSelector.substr(1) + '"></div></div>');
			var container = box.find(opts.stripeSelector);
			container.css('left', container.position().left);
			var items = container.find('.item');
			totalItems = items.length;
			shiftVal = items.eq(0).innerWidth();
			if (items.eq(1).length > 0) {
				spacing = items.eq(1).innerWidth() - shiftVal;
			}
			startX = container.position().left;
			posX = startX;
			objW = (shiftVal + spacing) * items.length - spacing;
			maxW = box.width();
			container.width(objW);
			var a = container.find('a');
			/*a.each(function () {
				showCaption($(this));
			});*/
			var pages = Math.ceil(objW / maxW);
			if (pages > 1) {
				box.append('<a href="" class="nav next"></a>').prepend('<a href="" class="nav prev"></a>');
				var nav = box.find('.nav');
				if ($('body').width() <= 980) nav.addClass('narrow');
				nav.click(function (e) {
					var target = $(e.target);
					var callback = null;
					if (target.hasClass('prev')) {
						e.preventDefault();
						if (timer) clearTimeout(timer);
						if (that.isPlayMode) callback = that.play;
						that.shift('prev', 1, callback);
					} else if (target.hasClass('next')) {
						e.preventDefault();
						if (that.isPlayMode) callback = that.play;
						that.shift('next', 1, callback);
					}
				});
				var html = '<div class="sliderNav">';
				for (var i = 0; i < pages; i++) html += '<a href="" class="sliderNavLink">' + (i + 1) + '</a>';
				html += '</div>';
				html = $(html);
				html.find('a').eq(0).addClass('active');
				box.append(html);
			}
			adjustNav();
			box.find('.sliderNavLink').click(function (e) {
				var target = $(this);
				e.preventDefault();
				if (timer) clearTimeout(timer);
				var index = target.parent().find('a').index(target);
				if (currentPage != index) {
					var offset = currentPage - index;
					var callback = (that.isPlayMode) ? that.play : null;
					var direction = (offset < 0) ? 'next' : 'prev';
					that.shift(direction, Math.abs(offset), callback);
				}
			});
			items.mouseenter(function () {
				if (that.isPlayMode) that.stop();
			}).mouseleave(function () {
				if (that.isPlayMode) that.play();
			});
			if (that.isPlayMode) that.play();
			if (opts.onAfterInit) opts.onAfterInit();
		}
	}
	that.play = function () {
		if (timer) clearTimeout(timer);
		timer = setTimeout(function () {
			currentPage++;
			if (currentPage < totalItems) {
				that.shift('next', 1, that.play);
			} else {
				currentPage = 0;
				that.shift('prev', totalItems, null);
				that.play();
			}
			
		}, opts.delay * 1000);
	};
	that.stop = function () {
		if (timer) clearTimeout(timer);
	};
	that.getOffset = function (index) {
		return currentPage - index;
	};
	function showCaption(obj) {
		var alt = obj.find('img').attr('alt');
		if (alt.length > 0) {
			var caption = obj.append('<div class="caption"><div class="text">' + alt + '</div><div class="bg"></div></div>').find('.caption').hide().fadeIn();
			caption.find('.bg').height(caption.height());
		}
	}
	function hideCaption(obj) {
		obj.find('.caption').fadeOut(function () {
			$(this).remove();
		});
	}
	that.shift = function (direction, offset, callback) {
		var time = 300;
		var moveX = getShiftSize(direction, offset);
		if (moveX !== 0) {
			posX += moveX;
			var obj = $(opts.selector).find(opts.stripeSelector);
			obj.animate({
				left: '+=' + moveX
			}, time, function() {
				adjustNav();
				if (callback) callback();
				if (opts.callback) opts.callback(currentPage);
			});
		}
	}
	function getShiftSize(direction, offset) {
		var moveX = 0;
		var itemsPerSpan = Math.floor(maxW / shiftVal);
		var shiftX = itemsPerSpan * (shiftVal + spacing) * offset;
		if (direction == 'next') {
			var minX = startX - objW + itemsPerSpan * (shiftVal + spacing) - spacing;
			moveX = (posX - shiftX < minX) ? posX - minX : shiftX;
			moveX = -moveX;
		} else {
			var maxX = startX;
			moveX = (posX + shiftX > maxX) ? maxX - posX : shiftX;
		}
		return moveX;
	}
	function adjustNav() {
		var container = $(opts.selector);
		var prev = container.find('.prev').removeClass('active').css('cursor', 'default');
		var next = container.find('.next').removeClass('active').css('cursor', 'default');
		if (getShiftSize('prev', 1) != 0) {
			prev.addClass('active').css('cursor', 'pointer');
		}
		if (getShiftSize('next', 1) != 0) {
			next.addClass('active').css('cursor', 'pointer');
		}
		var nav = container.find('.sliderNav');
		if (nav.length > 0) {
			var items = nav.find('a');
			var pageIndex = Math.ceil((Math.abs(posX - startX) - (items.length - 1) * spacing) / maxW);
			currentPage = pageIndex;
			items.removeClass('active').eq(pageIndex).addClass('active');
		}
	}
	init();
	return that;
};

CORE.Quotes = function (selector) {
	var that = this;
	var currentIndex = 0;
	var total = 0;
	var delay = 10; // secs
	init();
	function init() {
		var imgs = $(selector).find('img');
		total = imgs.length;
		if (total > 1) {
			imgs.hide().eq(0).show();
			rotate();
		}
	}
	function rotate() {
		setTimeout(function () {
			var item = $(selector);
			item.find('img:visible').fadeOut(250, function () {
				currentIndex++;
				if (currentIndex > total - 1) currentIndex = 0;
				item.find('img:eq(' + currentIndex + ')').fadeIn(250, function () {
					rotate();
				});
			});
		}, delay * 1000);
	}
	return that;
};

CORE.FancyHover = function (selector) {
	var that = this;
	init();
	function init() {
		var delay = 250;
		var thumbs = $(selector);
		thumbs.each(function () {
			var alt = $(this).find('img').attr('alt');
			var caption = $(this).wrapInner('<div class="wrapper"></div>').find('.wrapper').find('.caption');
		});
		thumbs.mouseenter(function () {
			var caption = $(this).find('.caption').show();
			caption.animate({left: 0}, delay);
		}).mouseleave(function () {
			var caption = $(this).find('.caption');
			caption.animate({left: -caption.innerWidth()}, delay, function () {
				caption.hide();
			});
		});
	}
	return that;
};

CORE.Partners = function () {
	var that = this;
	init();
	function init() {
		var content = $('#content');
		content.find('.intro h1 a, .intro .connect .bioLink').click(function (e) {
			e.preventDefault();
			var intros = content.find('.intro');
			var index = intros.index($(this).closest('.intro'));
			intros.removeClass('active').eq(index).addClass('active');
			content.find('.bio:visible').fadeOut(250, function () {
				content.find('.bio').eq(index).fadeIn(250);
			});
		});
		var intros = content.find('.intro');
		intros.mouseenter(function () {
			$(this).addClass('highlighted');
		}).mouseleave(function () {
			$(this).removeClass('highlighted');
		});
	}
	return that;
};

CORE.Popup = function () {
	//selector, isCloseOnClickOut, closeCallback
	var that = this;
	that.opts = (arguments[0].constructor == Object) ? arguments[0] : {selector: arguments[0]};
	if (!that.opts.selector) return alert('No popup selector specified.');
	if (!that.opts.popID) that.opts.popID = '#popup';
	if (!that.opts.overlayID) that.opts.overlayID = '#pageOverlay';
	if (!that.opts.closeSelector) that.opts.closeSelector = '.close';
	if (that.opts.isCloseOnClickOut !== false) that.opts.isCloseOnClickOut = true;
	if (!that.opts.transitionTime) that.opts.transitionTime = 0.2; // secs
	that.isActive = false;
	that.opts.win = (!that.opts.win) ? window : that.opts.win;
	var context = that.opts.win.document;
	init();
	function init() {
		$(context).click(function(e) {
			var target = $(e.target);
			if (that.isActive && target.attr('id') == that.opts.overlayID.replace('#', '') && that.opts.isCloseOnClickOut) {
				e.preventDefault();
				that.close();
			} else if (target.hasClass(that.opts.closeSelector.replace('.', '')) || target.hasClass('cancel')) {
				e.preventDefault();
				that.close();
			}
		});
		$(that.opts.selector, context).live('click', function (e) {
			e.preventDefault();
			that.open($(this).attr('href'));
		});
		$(context).keyup(function(e) {
			if (e.keyCode == 27) { // esc
				that.close();
			}
		});
		$(that.opts.win).bind('resize scroll', function () {
			that.position();
		});
	}
	that.prepare = function () {
		$(that.opts.popID + ', ' + that.opts.overlayID, context).remove();
		var html = '';
		html += '<div id="' + that.opts.popID.replace('#', '') + '"';
		if (that.opts.width) html += ' style="' + that.opts.width + 'px"';
		html += '></div><div id="' + that.opts.overlayID.replace('#', '') + '"></div>';
			
		$('body', context).append(html);
		that.pop = $(that.opts.popID, context).hide();
		that.overlay = $(that.opts.overlayID, context).css('opacity', 0.8).hide();
	}
	that.position = function () {
		that.pop = $(that.opts.popID, context);
		if (that.pop.length > 0) {
			var w = $('body', context).width();
			var h = $(context).height();
			var popW = that.pop.innerWidth();
			var popH = that.pop.innerHeight();
			that.pop.css({
				left: Math.floor($(that.opts.win).scrollLeft() + ($(that.opts.win).width() - popW) / 2) + 'px',
				top: Math.floor($(that.opts.win).scrollTop() + ($(that.opts.win).height() - popH) / 2) + 'px'
			});
			that.overlay.width(w);
			that.overlay.height(h);
		}
	}
	that.close = function () {
		that.pop = $(that.opts.popID, context);
		that.overlay = $(that.opts.overlayID, context)
		that.overlay.fadeOut(that.opts.transitionTime * 1000);
		that.pop.fadeOut(that.opts.transitionTime * 1000, function () {
			that.pop.remove();
			that.overlay.remove();
			if (that.opts.close) that.opts.close(); // close callback
		});
		that.isActive = false;
	};
	that.open = function (url) {
		that.isActive = true;
		that.prepare();
		that.pop = $(that.opts.popID, context);
		that.position();
		that.overlay.fadeIn(that.opts.transitionTime * 1000);
		that.pop.fadeIn(that.opts.transitionTime * 1000);
		that.pop.append('<div class="preloader">loading...</div>');
		$.ajax({
			type: 'GET',
			url: url,
			data: 'ajax=1',
			error: function(xhr, status, error) {
				alert('Ajax error has occurred.');
				that.close();
			},
			success: function(data) {
				data += '<a href="" class="close"></a>';
				that.pop.html(data);
				that.pop = $(that.opts.popID, context);
				that.position();
				if (that.opts.open) that.opts.open(); // open callback
			},
			complete: function () {
				that.pop.find('.preloader').remove();
			}
		});
	};
};

CORE.FormHandler = function () {
	var that = arguments.callee.prototype;
	if (arguments.length == 0) return alert('No parameters specified.');
	var opts = {};
	if (arguments[0].constructor == Object) {
		opts = arguments[0];
	} else {
		opts.selector = arguments[0];
	}
	opts.buttonSelector = ':input[type=submit]';
	if (!opts.errorFieldSelector) opts.errorFieldSelector = '.errorFld';
	if (!opts.errorMsgSelector) opts.errorMsgSelector = '.errorMarker';
	if (!opts.errorSummarySelector) opts.errorSummarySelector = '.errorSummary';
	if (!opts.antirobotFieldSelector) opts.antirobotFieldSelector = '.noErrors';
	if (!opts.isHaltOnSuccess) opts.isHaltOnSuccess = false;
	if (!opts.isHideButton) opts.isHideButton = false;
	var isSubmitting = false;
	var xhr = null;
	init();
	function checkErrors (frm, fld, callback) {
		if (xhr) xhr.abort();
		var url = frm.attr('action');
		var utils = new CORE.Utils();
		var isSubmit = (fld) ? 0 : 1;
		if (!fld) { // submit button clicked
			clearErrors();
			if (opts.isHideButton) {
				frm.find(opts.buttonSelector).hide().after('<div id="processing">Please wait, processing...</div>');
			} else {
				utils.fixButton(false, frm.find(opts.buttonSelector));
			}
		} else { // field lost focus
			clearErrors(fld);
		}
		xhr = utils.getJson({
			url: frm.attr('action'),
			data: frm.serialize() + '&isSubmit=' + isSubmit,
			error: function () {
				if (callback) callback();
				$('#jsError').remove();
				var button = frm.find(opts.buttonSelector).after('<div id="jsError" class="error">Unexpected AJAX error occurred.</div>');
				utils.fixButton(true, button);
			}
		}, function (data) {
			if (data != true) { // got errors
				if (callback) callback();
				var errors = data;
				if (!fld) { // check all fields
					//summaryFld.html('<div class="one"><div class="two"><strong>Please fix the following errors:</strong><ul></ul></div></div>');
					for (var errorFieldName in errors) showError(errors, errorFieldName);
					if (opts.isHideButton) {
						$('#processing').remove();
						$(opts.buttonSelector).show();
					} else {
						utils.fixButton(true, frm.find(opts.buttonSelector));
					}
					isSubmitting = false;
				} else { // check one field
					showError(errors, fld.attr('name'));
				}
			} else { // no error
				if (!fld) {
					frm.append('<input type="hidden" name="jsSuccess" value="1" />');
					if (!opts.isHaltOnSuccess) {
						frm.submit();
					} else if (opts.callback) {
						opts.callback();
						//utils.fixButton(true, frm.find(opts.buttonSelector));
					}
				}
			}
		});
		function showError(errors, errorFieldName) {
			var error = errors[errorFieldName];
			if (error) {
				if (!error.length) { // error is object (zend way)
					for (var i in error) {};
					error = error[i];
				}
				if (errorFieldName != 'error') { // field error
					var fld = frm.find(':input[name=' + errorFieldName + ']');
					if (fld) {
						if (!fld.is('[type=radio], [type=checkbox]')) fld.addClass(opts.errorFieldSelector.substr(1));
						fld.closest('.row').find(opts.errorMsgSelector).html(error);
					}
					//fld.after('<span class="' + opts.errorMsgSelector.substr(1) + '">' + error + '</span>');
				} else { // error summary
					frm.find(opts.errorSummarySelector).html(error);
				}
			}
		}
		function clearErrors(fld) {
			var msgObj;
			if (fld) {
				msgObj = fld.closest('.row').find(opts.errorMsgSelector);
			} else {
				fld = frm.find(opts.errorFieldSelector);
				msgObj = frm.find(opts.errorMsgSelector + ', ' + opts.errorSummarySelector);
			}
			msgObj.html('&nbsp;');
			fld.removeClass(opts.errorFieldSelector.substr(1));
		}
	}
	function init() {
		$(document).ready(function () {
			var utils = new CORE.Utils();
			var frm = $(opts.selector);
			frm.submit(function (e) {
				frm = $(this);
				var isValid = frm.find(':input[name=jsSuccess]').length;
				if (!isValid) { //frm.find(':input[name=' + opts.antirobotFieldSelector.substr(1) + ']').length == 0) {
					isSubmitting = true;
					e.preventDefault();
					checkErrors(frm, null);
				}
			});
			frm.find(':input[type!=submit]').not('.optional').blur(function (e) {
				if (!isSubmitting) {
					var fld = $(this);
					checkErrors(fld.closest('form'), fld);
				}
			});
			frm.append('<input type="hidden" name="' + opts.antirobotFieldSelector.substr(1) + '" value="secret" />');
		});
	}
};

CORE.Videos = function () {
	var that = this;
	if (!arguments[0]) return alert("Video settings are missing.");
	if (!arguments[0]['selector']) return alert("Video selector is missing.");
	that.selector = arguments[0].selector;
	that.videoSelector = '#pageSlider';
	that.isSupportVideo = isSupportVideo();
	that.isControlsRecognized = false;
	that.isPlaying = false;
	that.timer = null;
	that.slider = arguments[0].slider;
	that.isf4v = false;
	that.swfvars = null;
	var i = 0;
	init();
	function init() {
		//alert(that.isSupportVideo);
		updateHtml();
		var container = $(that.videoSelector);
		var containerOffset = container.offset();
		$('body').mousemove(function(e) {
			if (e.pageX >= containerOffset.left &&
				e.pageX <= containerOffset.left + container.width() &&
				e.pageY >= 0 &&
				e.pageY <= containerOffset.top + container.height()) {
					showControls();
			} else if (that.isControlsRecognized) {
				hideControls();
			}
		});
		$(document).click(function (e) {
			var target = $(e.target);
			if (target.hasClass('paused')) {
				e.preventDefault();
				that.pauseVideo(target.closest('.image'));
			} else if (target.hasClass('play')) {
				e.preventDefault();
				that.playVideo(target.closest('.image'));
			} else if (target.hasClass('nav') || target.hasClass('sliderNavLink')) {
				$(that.videoSelector + ' .video, object, embed').each(function () {
					that.pauseVideo($(this).closest('.image'));
				});
			}
		});
	}
	function updateHtml() {
		$(that.selector).each(function () {
			var rel = $(this).attr('rel');
			if (rel) {
				$(this).replaceWith(generateHtml(rel));
				if (that.isf4v) {
					swfobject.embedSWF(CORE.wwwroot + '/swfs/videoPlayer.swf', that.swfvars.id, 
							that.swfvars.dims.w, that.swfvars.dims.h, '9.0.0', CORE.wwwroot + '/swfs/expressInstall.swf', 
							that.swfvars.flashvars, that.swfvars.params);
					that.swfvars = null;
					that.isf4v = false;
				}
			}
		});
	}
	function generateHtml(urls) {
		urls = urls.split(',');
		var dimensions = {w: 923, h: 513};
		var html = '';
		if (that.isSupportVideo) { // supports video tag
			html += '<video width="' + dimensions.w + '" height="' + dimensions.h + '" class="video">';
			for (var i = 0; i < urls.length; i++) {
				if (/.mp4$/.test(urls[i])) {
					html += '<source src="' + urls[i] + '" type="video/mp4" />';
				}
			}
			html += '</video>';
		} else { // does not support video tag
			for (var i = 0; i < urls.length; i++) {
				if (/.f4v$/.test(urls[i])) {
					// setup vars needed for swfobject
					that.isf4v = true;
					that.swfvars = {};
					that.swfvars.dims = dimensions;
					that.swfvars.id = urls[i].replace('.f4v', '');
					that.swfvars.flashvars = {
						movie: urls[i],
						autoplay: 'on',
						muteonly: 'false',
						volume: '0',
						accentcolor: '0x31b8e9'
					};
					that.swfvars.params = {
						menu: 'false',
						allowFullScreen: 'true',
						wmode: 'opaque',
						bgcolor: '#000000'
					};
					html += '<div id="' + that.swfvars.id + '" class="video"></div>';
				}
			}
		}
		html += '<a href="#" class="controlls play"></a>';
		return html;
	}
	function hideControls() {
		$(that.videoSelector + ' .controlls').hide();
	}
	function showControls() {
		$(that.videoSelector + ' .controlls').show();
	}
	that.playVideo = function (container) {
		var video;
		that.isControlsRecognized = true;
		if (that.isSupportVideo) {
			video = container.find('video')[0];
			video.play();
			//if (!timer) checkVideoStatus();
		} else {
			video = container.find('object, embed')[0];
			video.playFlv();
		}
		that.isPlaying = true;
		that.slider.isPlayMode = false;
		if (that.timer) clearInterval(that.timer);
		that.timer = setInterval(function () {
			checkStatus(container);
		}, 500);
		container.find('.controlls').addClass('paused');
		hideControls();
	};
	that.pauseVideo = function (container) {
		var video;
		if (that.isSupportVideo) {
			video = container.find('video')[0];
			video.pause();
			//if (timer) clearInterval(timer);
		} else {
			video = container.find('object, embed')[0];
			video.pauseFlv();
		}
		that.isPlaying = false;
		that.slider.isPlayMode = true;
		if (that.timer) clearInterval(that.timer);
		container.find('.controlls').removeClass('paused');
		that.isControlsRecognized = false;
		showControls();
	};
	function checkStatus(container) {
		var video;
		if (that.isSupportVideo) {
			video = container.find('video')[0];
			if (video.ended) {
				that.pauseVideo(container);
				video.currentTime = 0;
			}
		} else {
			video = container.find('object, embed')[0];
			//location.hash = video.isFlvEnded() + ' ' + i;
			if (video.isFlvEnded()) {
				that.pauseVideo(container);
			}
		}
		i++;
	}
	function isSupportVideo() {
		var result = false;
		//return false;
		if (isSupportH264()) {
			result = true;
		//} else if (isSupportOgg()) {
			//result = true;
		//} else if (isSupportWebm()) {
			//result = true;
		}
		if ($.browser.msie && $.browser.version > 8) result = false; // disable for IE9
		return result;
	}
	function isSupportH264() {
		var v = document.createElement('video');
		return v.canPlayType && v.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
	}
	function isSupportOgg() {
		var v = document.createElement('video');
		return v.canPlayType && v.canPlayType('video/ogg; codecs="theora, vorbis"');
	}
	function isSupportWebm() {
		var v = document.createElement('video');
		return v.canPlayType && v.canPlayType('video/webm; codecs="vp8, vorbis"');
	}
};
