/**
 * 
 * Global Script for Brehm Project Sites
 * 
 * @author Michael Gilley <michael@180bydesign>
 * @copyright 2010 Brehm Center <www.brehmcenter.com>
 * @legal All Rights Reserved. Do not copy without permission.
 * 
 */

var Brehm = (function ($, undefined) {
	return {
		fire: function() {
			for (var i in Brehm.init) {
				Brehm.init[i]();
			}
		},
		init: {
			// Brehm menu
			menu: function() {
				var $megas = $('li.mega', '#brehm_links');
				if ( $megas.length ) Brehm.megaMenu.init( $megas );
			},
			// modal window setup
			modal: function() {
				if ( ! isMobile || typeof isMobile === "undefined" ) Brehm.modal.init();
			},
			// copyright for hero images
			heroCopy: function() {
				var $hero = $('.brehm_hero_copy');
				if ( $hero.length ) Brehm.hero( $hero );
			},
			// Brehm Faculty Pages
			faculty: function() {
				var $bx = $('.boxcallout');
				if ( $bx.length ) Brehm.boxcallout( $bx );
			},
			// Brehm Conversations Page General
			convos: function() {
				if ( $('.conversations').length ) Brehm.conv.init();
			},
			// All paginate instants
			paginate: function() {
				Brehm.paginate.init();
			},
			// All msDropDowns
			msDropDown: function() {
				var $selects = $('.msDropDown');
				if ( $selects.length ) Brehm.msDropDowns( $selects );
			},
			// All Cycles/Slideshows
			cycles: function() {
				var $cycles = $('.cycle');
				if ( $cycles.length ) Brehm.cycle( $cycles );
			},
			// All field instruction tooltips
			tooltips: function() {
				var $inst = $('.ui-tooltip');
				if ( $inst.length ) Brehm.toolTips( $inst );
			},
			// Exhibition page
			exh: function() {
				var $exh = $('.exh_img_thumbs');
				if ( $exh.length ) Brehm.exhibitions( $exh );
			},
			// jPlayer Audio
			/*dynLabels: function() {
				Brehm.utilities.dynamicLabels();
			},*/
			
			// Dynamic Labels
			dynLabels: function() {
				Brehm.utilities.dynamicLabels();
			}
		},
		hero: function($hero) {
			var $credit = $('.brehm_hero_credit');
			
			$hero.hover(function() {
				$credit.stop(true, true).fadeIn(250);
			}, function() {
				$credit.stop(true, true).fadeOut(150);
			});
		},
		modal: {
			init: function() {
				// init modal window
				Brehm.modalObj = $('#modal').dialog({
					modal: true,
					width: 576,
					autoOpen: false,
					open: function(even, ui) {
						$(document).bind('click.modalclose', function(e) {
							if ($(e.target).is('.ui-widget-overlay')) {
								$('#modal').dialog('close');
							}
						});
					},
					close: function(event, ui) {
						$(this).html('');
						$(document).unbind('click.modalclose');
					}
				});
				
				// auto modal links
				$('a.modallink').click(function() {
					Brehm.modal.open( $(this).attr('href'), this );
					return false;
				});
				
				// auto larger modal links
				$('a.modallinkbig').click(function() {
					Brehm.modal.openLarge( $(this).attr('href'), this );
					return false;
				});
			},
			open: function(url, el) {
				if (typeof url === 'undefined' || url === '') return;
				// load the modal template into the modal and open it!
				$(el).addClass('loading');
				
				Brehm.modalObj.load(url, function() {
					// truncate modal text
					Brehm.utilities.truncate( Brehm.modalObj.find('.prayer_body') );
					// run dynamic labels
					Brehm.utilities.dynamicLabels( Brehm.modalObj );
					// check for pagination
					Brehm.paginate.init( Brehm.modalObj, false );
					Brehm.modalObj.dialog('open');
					
					// tooltips
					Brehm.toolTips( false, Brehm.modalObj );
					
					$(el).removeClass('loading');
				});
			},
			openLarge: function(url) {
				var windowW = Math.floor( $(window).width() * .95 ),
					windowH = Math.floor( $(window).height() * .95 ),
					$frame = $('<iframe/>');
				
				$frame.attr({
					src: url,
					id: 'modalFrame'
				}).addClass('noHeight');
				
				Brehm.modalObj
					.css('overflow', 'visible') // This is to fix an iframe width bug with scrolls
					.append($frame)
					.dialog('option', 'width', windowW)
					.dialog('option', 'height', windowH)
					.bind('dialogclose.big', function(event, ui) {
						// return modal to it's original size
						$(this)
							.dialog('option', 'width', 576)
							.dialog('option', 'height', 'auto')
							.css('overflow', '') // restore the overflow like we want it
							.unbind('dialogclose.big');
					})
					.dialog('open');
			}
		},
		megaMenu: {
			menutime: null,
			$container: null,
			init: function($megas) {
				var $megamenus = $megas.find('.megamenu'),
					menuConfig = { timeout: 0 },
					$container = null,
					mm = this;

				if ( ! Config.megaMenus.enabled ) return;
				
				// let's link all megamenus to their parents
				$megas.each(function(i) {
					$(this).find('.megamenu').andSelf().data('menuindex', i);
				});
				
				// No click on menu unless it's IE 7 or lower
				if (! (Config.agent.name == 'ie' && Config.agent.version < 8) && Config.megaMenus.disableClick) {
					$megas.find('a:first').click(false);
				}
					
				// we need to move all megamenus to a container under the menu
				$('<div id="' + Config.megaMenus.menuId + '"/>').insertAfter('#' + Config.megaMenus.headerId);
				
				this.$container = $container = $('#' + Config.megaMenus.menuId);
				
				// do some housework
				$megamenus
					// get and record the height of each item
					.each(function() {
						var $this = $(this);
						$this.data('height', mm.getHeight( $this ));
					})
					// add a hover effect
					.hover(function() {
						$(this).addClass('hover');
					}, function() {
						$(this).removeClass('hover');
					});
				
				// init hover effect for menu
				$.extend(true, menuConfig, Config.megaMenus.menuConfig, {
					over: function() {
						var $this = $(this),
							index = $this.data('menuindex'),
							$menu = $this.children('.megamenu');
						
						$this.addClass('hover');
						mm.openMenu( $menu );
					},
					out: function() {
						var $this = $(this),
							$menu = $this.children('.megamenu');
						
						$this.removeClass('hover');
						mm.closeMenu( $menu );
					}
				});
				
				$megas.hoverIntent( menuConfig );
			},
			openMenu: function($menu) {
				var $cont = this.$container,
					mh = $menu.data('height'),
					isActive = $('.megamenu').is('.active'),
					inSpeed = (isActive) ? Config.megaMenus.fastTransition : Config.megaMenus.slowTransition,
					mm = this;
				
				$cont.stop(true, true).animate({height: mh}, Config.megaMenus.slowTransition, Config.easing, function() {
					$menu.css('z-index', 52).stop(true, true).fadeIn( inSpeed ).addClass('active');
				});
			},
			closeMenu: function($menu) {
				var $cont = this.$container,
					megaIsHover = $('.mega').is('.hover'),
					outSpeed = (megaIsHover) ? Config.megaMenus.fastTransition : Config.megaMenus.slideTransition,
					mm = this;
				
				$menu.removeClass('active').css('z-index', 50).stop(true, true).fadeOut( outSpeed );
				
				if (! megaIsHover) {
					$cont.stop(true, true).animate({height: 0}, Config.megaMenus.slowTransition, Config.easing);
				}
			},
			getHeight: function($item) {
				var height = 0;
				
				// move item off of page and display
				$item
					.css({
						position: 'absolute',
						visibility: 'hidden',
						opacity: 0,
						top: -10000,
						left: -10000
					})
					.show();
				
				height = $item.outerHeight();
				
				$item.removeAttr('style').hide();
				
				return height;
			}
		},
		boxcallout: function($bx) {
			var $links = $bx.find('a'),
				$cinfo = $('.calloutinfo');
			
			$links
				.hover(function() {
					$(this).addClass('hover');
				}, function() {
					$(this).removeClass('hover');
				})
				.click(function(e) {
					var $this = $(this)
						link = $this.attr('data-link');
				
					e.preventDefault();
					
					// if the link is already active do nothing
					if ($this.is('.active')) return false;
					
					// reset the stage
					$bx.findAndRemoveClass('active');
					$cinfo.children('div:visible').hide();
					
					// now show the info we really need
					$this.addClass('active');
					$('#'+link).show();
				});
		},
		cycle: function($stage) {
			// Do we need to segment this set first?
			if ($stage.data('segment')) {
				this.segment( $stage );
			}
			
			// item hover for any interior info
			$stage.find('.item').hover(function() {
				$(this).toggleClass('hover');
			});
			
			// Cycle plugin
			$stage.cycle({
				fx: 'scrollHorz',
				easing: 'easeOutExpo',
				timeout: 4000,
				next: '#' + $stage.data('next'),
				prev: '#' + $stage.data('prev')
			}).cycle('pause');
		},
		segment: function($stage) {
			var segs = $stage.data('segment') || 10,
				c = $stage.children().get(),
				rows = Math.ceil(c.length / segs);
			
			for (var i=1; i <= rows; i++) {
				var $row = $('<div class="row"/>'),
					a;
				
				a = (segs < c.length) ? c.splice(0, segs) : c;
				
				$row.append(a).appendTo($stage);
			}
		},
		toolTips: function($tips, context) {
			context = context || 'body';
			
			if (typeof $tips == 'boolean' && !$tips) {
				$tips = $('.ui-tooltip', context);
				if ( $tips.length === 0 ) return false;
			}
			
			$tips.each(function() {
				var $t = $(this),
					dir = ($t.is('.tool_right')) ? ' tool_right' : '';
					tool = '';
				
				tool += '<div class="tooltip'+dir+'">';
				tool += '<a href="#tooltip" class="q" data-field="'+$t.attr('id')+'">Field Instructions</a>';
				tool += '<div class="box"><span class="a"></span><div class="w">';
				tool += $t.html();
				tool += '</div></div>';
				tool += '</div>';
				
				$t.replaceWith( tool );
			});
			
			$('.tooltip a.q', context)
				.hover(function() {
					$(this).addClass('hover').next().stop(true, true).fadeIn(250);
				}, function() {
					$(this).removeClass('hover').next().stop(true, true).fadeOut(150);
				})
				.click(function() {
					var fid = $(this).data('field'),
						id = fid.substr( fid.indexOf('_')+1 );
					
					$('input[name="field_id_'+id+'"]').focus();
					return false;
				});
		},
		paginate: {
			init: function(context, checkForChildren) {
				var check = ':visible',
					pag = this;
				
				context = context || "body";
				
				if (!checkForChildren) check = '';
				
				$('.gen_paginate', context).each(function() {
					var $this = $(this),
						limit = $this.data('limit') || 10,
						$items;
						
					check = ($this.data('hidden') && $this.data('hidden') === 0) ? ':visible' : check;
					$items = $this.find('.paginate_items').children(check);
					
					// are there less than the limited items?
					if ($items.length <= limit) return;
					
					// hide all the later items
					$items.filter(':gt('+(limit-1)+')').addClass('pag-hide');
					
					// create page menu and place it
					$page = pag.createPageMenu($items, limit).insertAfter( $this );
					
					// create events
					$page.find('a.tab').click( pag.switchPage );
					$page.find('.nav a').click( pag.navSwitch );
				});
			},
			createPageMenu: function($items, limit) {
				var $pageM = $('<div class="pagemenu"/>'),
					nav = '<div class="nav"><a href="#prev" class="prev">Prev</a><a href="#nxt" class="nxt">Next</a></div>',
					pages = Math.ceil( $items.length / limit ),
					numbers = '';
				
				for (var i=1; i<=pages; i++) {
					numbers += '<a href="#page-'+i+'" class="tab';
					numbers += (i==1) ? ' active' : '';
					numbers += '">'+i+'</a>';
				}
				
				$pageM.append(nav + numbers).data('pages', pages);
				
				return $pageM;
			},
			switchPage: function(e) {
				var $this = $(this),
					index = $this.index() - 1,
					$set = $this.parent().prev(),
					$items = $set.find('.paginate_items').children(),
					limit = $set.attr('data-limit') || 10,
					total = $items.length,
					x,y;
					
				e.preventDefault();
				
				if ( $this.is('active') )  return;
				
				// remove present active state
				$this.parent().findAndRemoveClass('active').end().end().addClass('active');
				
				// switch page views
				x = limit * index;
				y = limit * (index+1);
				
				$items.addClass('pag-hide').slice(x,y).removeClass('pag-hide');
			},
			navSwitch: function(e) {
				var $this = $(this),
					$menu = $this.parents('.pagemenu'),
					$tabs = $menu.find('.tab'),
					active = $tabs.filter('.active').index(),
					goIndex;
				
				e.preventDefault();
				
				// don't do anything if there's only one page!
				if ( $menu.data('pages') == 1 ) return;
				
				if ($this.is('.prev')) {
					// do prev
					goIndex = active - 1 || $tabs.length;
				} else {
					// do next
					goIndex = (active + 1 <= $tabs.length) ? active + 1 : 1;
				}
				
				$tabs.eq(goIndex-1).trigger('click');
			},
			refresh: function(context, checkForChildren) {
				context = context || '';
				$('.pagemenu', context).remove();
				$('.pag-hide', context).removeClass('pag-hide');
				this.init( context, checkForChildren );
			}
		},
		msDropDowns: function($selects) {
			// take care of custom drop downs
			// first we need to play nicely with the msDropDown plugin: selects must have an id
			$('.msDropDown').each(function(i) {
				if ( $(this).attr('id') === "" ) $(this).attr('id', 'msDropDown-'+i);
			}).msDropDown();
		},
		conv: {
			init: function() {
				var $media = $('#embeds'),
					$comments = $('#convo_comments'),
					$replies = $comments.find('.replyto'),
					hash = document.location.hash.substr(1);
				
				// hash for starting conversation: #start
				if (hash == 'start') {
					Brehm.modal.open( $('#startconvo').attr('href') );
				}
				
				// login button for convo box
				$('.login_other a').live('click', function() {
					var $t = $(this),
						$cont = $('.comment_login_other');
					
					if (! $t.is('.open')) {
						$cont.animate({height: 421}, 450, Config.easing);
						$t.addClass('open').text('Register');
					} else {
						$cont.animate({height: 38}, 450, Config.easing);
						$t.removeClass('open').text('Login Again');
					}
					
					return false;
				});
				
				// embedded media on article page
				if ( $media.length ) this.media( $media );
				
				// comments functionality
				if ( $comments.length ) this.comments( $comments );
				
				// handle replies
				if ( $replies.length ) this.replies.init( $replies );
			},
			media: function($media) {
				$media.find('.embedplay').click(function(e) {
					e.preventDefault();
					
					$(this).hide().next('.embedcode').show();
				});
			},
			comments: function($comments) {
				// bundle reply tos
				$('.entry + .replyto').each(function() {
				    var $b = $(this).nextUntil(':not(.replyto)').andSelf().add( $(this).prev().get() );
					
					$b.wrapAll('<div class="bundle"/>');
				});
				
				// comments search
				this.search( $comments );
				
				// let's do sorting
				this.filter( $comments );
				this.sort( $comments );
				
				// ajax firing comment box
				// THIS NEEDS FIXING!!
				// this.commentSubmit( $comments );
				
				// reply button
				$comments.delegate('a.reply', 'click', function() {
					var $form = $(this).closest('.comment').find('.replytoform'),
						$replyTos = $('.replytoform:visible');
					
					$replyTos.slideUp(250).find('textarea').val('');
					
					$form.slideDown(250).find('textarea').focus();
					
					return false;
				});
				
				// handle replytoforms
				$('.replytoform .close').live('click', function() {
					$(this).parent().slideUp(250).find('textarea').val('');
					return false;
				});
				
				$('.replytoformform').submit(function(e) {
					var $f = $(this),
						$info = $f.find('.info input');
					
					if ($info.length > 0) {
						$info.each(function() {
							var $t = $(this);
							
							if ($t.is('.req') && $t.val() == '') {
								$t.focus();
								e.preventDefault();
								return false;
							}
						});
					}
				});
				
				// we'll automate this later!
				$('.ratings a').live('click', function() {
					var $t = $(this),
						url = $t.attr('href')
						txt = $t.text();
					
					if ($t.is('.clicked')) return false;
					$t.addClass('clicked');
					
					$.ajax({
						url: url,
						error: function(req, textStatus, er) {
							console.error(er);
						},
						success: function(data) {
							if (data == "success") {
								// update the site front count
								var c = txt.match(/\d+/);
								if (c != null && c.length == 1) {
									txt = txt.replace(c[0], parseInt(c[0])+1);
								} else {
									txt = txt + ' ('+1+')';
								}
								$t.text(txt);
							} else {
								console.debug(data);
							}
						}
					});
					
					return false;
				});
				
				// is there a comments anchor tag?
				if (document.location.hash.substr(1) == "comments") {
					// let's not scare people
					setTimeout(function() {
						$.scrollTo('#convo_commentform', Config.pageScrollSpeed, Config.easingOut);
					}, 1000);
				}
			},
			search: function($comments) {
				$('#commentsearchform').submit(false);
				
				$('<div class="noresults">'+Config.noResultsText+'</div>').hide().prependTo('#comment_entries');
				
				// quicksearch fires the onAfter callback on load so we need to NOT init pagination
				// on the first run; see onAfter below
				$('#comment_search_q').addClass('loading');
				
				$('#comment_search_q').quicksearch('#comment_entries .paginate_items > div', {
					noResults: '.noresults',
					onAfter: function() {
						if ($('#comment_search_q').is('.loading')) {
							$('#comment_search_q').removeClass('loading');
							return;
						}
						Brehm.paginate.refresh($comments, true);
					}
				});
			},
			filter: function($comments) {
				var $filter = $('#featured_comments'),
					com = this;
				
				if ($filter.val() == "featured") {
					com.showFeatured( $comments );
				}
				
				$filter.change(function() {
					var val = $(this).val();
					
					if (val == "featured") {
						com.showFeatured( $comments );
					} else {
						$comments.findAndRemoveClass('feathide');
					}
					
					// refresh pagination
					Brehm.paginate.refresh($comments, true);
				});
			},
			showFeatured: function($comments) {
				$comments.find('.comment:not(:has(.feat))').each(function() {
					var $t = $(this);
					$t.addClass('feathide');
					if ($t.is('.entry') && $t.parent().is('.bundle')) $t.parent().addClass('feathide');
				});
			},
			sort: function($comments) {
				var $sort = $('#sort'),
					$c, $copy;
				
				$sort.change(function() {
					var $set = $('#comment_entries'),
						set = $set.data('sort'),
						val = $(this).val();
					
					if (set != val) {
						$parent = $comments.find('.paginate_items');
						$c = $parent.children();
						$copy = $.makeArray($c);
						$copy.reverse();

						$parent.empty().append( $copy );
						
						$set.data('sort', val);

						// refresh pagination
						Brehm.paginate.refresh($comments, true);
					}
				});
			},
			replies: {
				init: function($replies) {
					var res = this;
					
					// begin with replies toggled by default
					$replies.each(function() {
						res.toggleReply(this, true);
					});
					
					// reply tick marks
					$replies.find('.tickme').click(function() {
						var $t = $(this),
							$re = $t.closest('.comment');
						
						res.toggleReply($re);
						return false;
					});
				},
				toggleReply: function($re, jump) {
					var $re = ($re.selector) ? $re : $($re),
						open = ($re.is('.closed')) ? false : true,
						jump = jump || false;
					
					$.fx.off = jump;
					if (open) {
						$re
							.find('.cbody, .cdate, .ratings').hide()
							.end()
							.find('.comment_avatar img')
								.animate({height: 20, width: 20}, 250, Config.easing)
								.end()
							.animate({paddingTop: 12}, 250, Config.easing)
							.addClass('closed');
					} else {
						$re
							.find('.cbody, .cdate, .ratings').show()
							.end()
							.find('.comment_avatar img')
								.animate({height: 72, width: 72}, 250, Config.easing)
								.end()
							.animate({paddingTop: 35}, 250, Config.easing)
							.removeClass('closed');
					}
					$.fx.off = false;
				}
			},
			commentSubmit: function($comments) {
				var $form = $('.commentform'),
					$ret, oRET, $eId;
				
				if (! $form.length) return;
				
				$form.submit(function(e) {
					var $this = $(this);
					
					e.preventDefault();
					
					// do some quick housekeeping stuff before ajax
					$this.addClass('processing');
					$ret = $this.find(':hidden[name="RET"]');
					$eId = $this.find(':hidden[name="entry_id"]');
					oRET = $ret.val();
					$ret.val('conversations/ajax_commentlatest/'+$eId.val()+'/');
					
					$.ajax({
						type: 'POST',
						url: $this.attr('action'),
						data: $this.serialize(),
						cache: false,
						success: function(data) {
							var $insert;
							
							// house keeping
							$this.removeClass('processing');
							$ret.val( oRET );
							$form.find('textarea').val('').trigger('blur');
							
							// inject comment data
							$comments.find('.paginate_items').prepend( data );
							
							// is the new comment odd or even?
							/*if ($comments.find('.comment:first').is('.odd')) {
								$data.addClass('even');
							} else {
								$data.addClass('odd');
							}*/
							
							// $data.effect('hightlight');
							
							Brehm.paginate.refresh($comments, true);
						}
					});
				});
			}
		},
		exhibitions: function($exh) {
			var $thumbs = $exh.find('.thumb'),
				$lmedia = $('#exh_media');
			
			$thumbs.click(function(e) {
				var $this = $(this),
					row = $this.data('row'),
					$lset = $lmedia.find('.row_'+row);
					
				e.preventDefault();
				
				// is this the currently displayed exhibit piece?
				if ( $lset.first().is('.active') ) return false
				
				// if jplayer is using playlist - use thumbs to change it
				
				// have no idea how to do this ... ha!
				
				/*
				$("#jquery_jplayer_1").jPlayer("play");
				
				$(this.jquery_jplayer_1.playlist + "_item_" + $lset).data("index", i).click(function() {
					var index = $(this).data("index");
					if(self.current !== index) {
						self.playlistChange(index);
					} else {
						$(self.cssSelector.jPlayer).jPlayer("play");
					}
					$(this).blur();
					return false;
				});
				*/
				
				
				// hide the currently showing piece
				$lmedia.findAndRemoveClass('active');
				
				// show the one we want
				$lset.addClass('active');
			});
		},
		utilities: {
			truncate: function($obj, length) {
				len = length || 125;
				$obj.jTruncate({ length: len });
			},
			dynamicLabels: function(context) {
				context = context || "body";
				$('.dynamic_label label', context).inFieldLabels();
			}
		}
	}
})(jQuery);
