
// twitter plugin
(function($){

	$.tweet = (function() {
	
		var returned = function() {
			return this.initialize.apply(this, arguments);
		};
		
		returned.prototype = {
			defaults: {
				username: "intouchsol",
				count: 10,
				refresh: false, // twitter won't return new updates more frequently than every 60 seconds. set to false to disable.
				template: function(obj) {
					var node = $(
					"<div class='tweetItem'>" +
						"<div class='user'>" +
							obj.user +
						"</div>" +
						"<div class='tweet'>" +
							obj.text +
						"</div>" +
						"<div class='date'>" +
							obj.created_at +
						"</div>" +
					"</div>"					
					);
					return node;
				},
				loading: "<div class='tweetLoading'></div>", // loading markup
				maxlength:  false,
				cascadeIn: false,
				cascadeOut: false, // cascade the showing and hiding of tweets.
				animateOut: {
					enabled: true, // boolean whether tweets should animate
					css: { opacity: 1}, // object of css properties to apply BEFORE the animation
					animate: { // object of $.animate arguments
						properties: {
							opacity: 0
						},
						duration: 500,
						easing: "linear",
						callback: function() {
							$(this).remove();
						}		
					}
				}, 
				animateIn: {
					enabled: true,
					css: {
						opacity: 0
					},
					animate: { 
						properties: {
							opacity: 1
						},
						duration: 500,
						easing: "linear",
						callback: function() {}					
					}
				}
			},			
			
			timer: null,
			tweets: {},
			
			initialize: function(selector, options) {
				var opts = this.opts = $.extend({}, this.defaults, options);			
				this.elements = $(selector);
				this.timeline = opts.timeline || "http://api.twitter.com/1/statuses/user_timeline.json?screen_name=" + opts.username + "&count=" + opts.count + "&callback=?";
				this.json = null;
				this.tweets = null;
				this.latest_id = null;
				
				var self = this;
				
				// compile animate funcs
				this.animateOutFunc = (function() {
					var returned;
					if (opts.animateOut.enabled) returned = function(index, tweet, parent) {
						$(tweet).css(opts.animateOut.css).animate(
							opts.animateOut.animate.properties, 
							opts.animateOut.animate.duration, 
							opts.animateOut.animate.easing, 
							opts.animateOut.animate.callback
						);													
					}
					else returned = function(index, tweet, parent) {
						$(tweet).hide().remove();						
					}
					
					return returned;
				})();
				
				this.animateInFunc = (function() {
					var returned;
					if (opts.animateIn.enabled) returned = function(index, tweet, parent) {
						
						$(tweet).css(opts.animateIn.css).appendTo(parent).animate(
							opts.animateIn.animate.properties, 
							opts.animateIn.animate.duration, 
							opts.animateIn.animate.easing, 
							opts.animateIn.animate.callback
						);									
					}
					else returned = function(index, tweet, parent) {
						$(tweet).appendTo(parent);
					}
					
					return returned;
				})();								
				// if binds were passed in
				if (opts.binds) $(this).bind(opts.binds);
				
				// kick it off
				this.getTweets();
				
				// if it should auto update
				if (opts.refresh) {
					var self = this;
					(function refreshTweets() {
						clearTimeout(self.timer);
						setTimeout(function() {
							self.getTweets();
							refreshTweets();
						}, opts.refresh)
					})();					
				};
				
				return this;
			},
			
			load: function(tweets) {
				var self = this,
					opts = this.opts,
					newTweets = {},
					animateOut = opts.animateOut,
					animateIn = opts.animateIn;
				
				
				// make magic
				this.elements.each(function(i, el) {
					var tweetsClones = [],
						currTweets,
						timer = 0;
					
					// if there's currently tweets
					if (self.tweets && self.tweets[el]) {						
						currTweets = $(self.tweets[el]);
						currTweets.each(function(j, tweet) {							
							if (opts.cascadeOut) {								
								setTimeout(function() {
									self.animateOutFunc.apply(self, [j, tweet, el]);
								}, timer)
								timer+=opts.cascadeOut
							}
							else
								self.animateOutFunc.apply(self, [j, tweet, el]);
						});
						$(currTweets).remove();
					}
					timer = 0;
					tweets.each(function(j, tweet) {
						var clone = $(tweet).clone();						
						if (opts.cascadeIn) {
							setTimeout(function() {
								self.animateInFunc.apply(self, [j, clone, el]);
							}, timer)
							timer+=opts.cascadeIn
						}
						else
							self.animateInFunc.apply(self, [j, clone, el]);						
						
						tweetsClones.push(clone)
					});
					// store element references to ALL tweets
					// for easy removal later
					newTweets[el] = tweetsClones;
				});
				
				this.tweets = newTweets;				
				
				$(this).trigger("tweet.load");
				
			},
			
			getTweets: function(func) {
				var self = this,
					loading = $(this.opts.loading);
					
				if (this.latest_id === null) loading.appendTo(this.elements);				
				
				$.getJSON(this.timeline, function(data) {										
					if (!$.isArray(data)) return;
					
					var isNew = !!!(self.latest_id === data[0].id);
					
					self.latest_id = data[0].id || self.latest_id;
					
					if (data.length > self.opts.count) data = data.slice(0, self.opts.count);
					
					self.json = data;
					
					loading.remove();
					if (isNew) self.load(self.build(data));
					
					$(self).trigger("tweet.data");
				});										
			},
			
			build: function(json) {
				var self = this,
					returned = [],
					parsedText = (function() {
						var parsefunc = function(txt) {
							var parsed = txt;
							
							parsed = linkUrl.call(self, parsed);
							parsed = linkUser.call(self, parsed);
							parsed = linkHash.call(self, parsed);
							
							return parsed;							
						}
							
						if (self.opts.maxlength && self.opts.maxlength < 140) {
							
							var original = parsefunc;
							parsefunc = function(txt) {								
								var strarr = txt.replace(/^\s+|\s+$/g, "").replace(/\s+/g, " ").split(/\s/g),
									maxcount = self.opts.maxlength,
									count = 0,
									newtxt = "";
									
								for (var x = 0, l = strarr.length; x < l; x++) {									
									var len = strarr[x].length;
									if (count + len > maxcount) break;
									else {											
										count += len;	
										newtxt = newtxt + strarr[x] + " ";
									}
								}
								
								newtxt.replace(/\s$/g, "");
								newtxt += "...";
								
								return original.call(self, newtxt);
							};
						}						
						return parsefunc;
					})();
				
				
				$(json).each(function(index, tweet) {					
					var node = self.opts.template({
						user: tweet.user.name,
						text: parsedText(tweet.text),
						created_at: relativeTime.call(self, tweet.created_at)
					});

					returned.push(node);					
				});
				
				return $(returned);
			}		
			
			
		};

		// private functions
		var linkUrl = function(str) {			
			var regexp = /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi;
			return str.replace(regexp,"<a href=\"$1\">$1</a>");			
		},
		
		linkUser = function(str) {			
			var regexp = /[\@]+([A-Za-z0-9-_]+)/gi;
			return str.replace(regexp,"<a href=\"http://twitter.com/$1\">@$1</a>");			
		},
		
		linkHash = function(str) {			
			var regexp = /(?:^| )[\#]+([A-Za-z0-9-_]+)/gi;
			return str.replace(regexp, ' <a href="http://search.twitter.com/search?q=&tag=$1&lang=all&from='+ this.opts.username + '%2BOR%2B' +'">#$1</a>');			
		},		
		
		parse_date = function(date_str) {
		  // The non-search twitter APIs return inconsistently-formatted dates, which Date.parse
		  // cannot handle in IE. We therefore perform the following transformation:
		  // "Wed Apr 29 08:53:31 +0000 2009" => "Wed, Apr 29 2009 08:53:31 +0000"
		  return Date.parse(date_str.replace(/^([a-z]{3})( [a-z]{3} \d\d?)(.*)( \d{4})$/i, '$1,$2$4$3'));
		},		
		
		relativeTime = function(time_value) {
		  var parsed_date = parse_date(time_value);
		  var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
		  var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
		  var r = '';
		  if (delta < 60) {
		r = delta + ' seconds ago';
		  } else if(delta < 120) {
		r = 'a minute ago';
		  } else if(delta < (45*60)) {
		r = (parseInt(delta / 60, 10)).toString() + ' minutes ago';
		  } else if(delta < (2*60*60)) {
		r = 'an hour ago';
		  } else if(delta < (24*60*60)) {
		r = '' + (parseInt(delta / 3600, 10)).toString() + ' hours ago';
		  } else if(delta < (48*60*60)) {
		r = 'a day ago';
		  } else {
		r = (parseInt(delta / 86400, 10)).toString() + ' days ago';
		  }
		  return 'about ' + r;		
		};		

		
		return returned;
		
	})();


})(jQuery);

// homepage media box
(function($) {
	
	this.HomeMediaBox = {
		opts: {
			borderStart: "#151515",
			borderEnd: "#000000",
			borderWidth: 20,
			width: 700,
			height: 444
		},
		
		init: function(selector) {			
			this.element = $(selector);
			this.build();
			this.attach();
			
			return this;
		},
		
		attach: function() {
			var self = this;
			
			this.position = $.proxy(this.position, this);			
			this.closeBtn.bind("click", $.proxy(this.hide, this));
			this.wrapper.bind({
				"mouseenter": function() {
					self.closeBtn.show();
				},
				"mouseleave": function() {
					self.closeBtn.hide();
				}
			});			
			
			return this;
		},
		
		build: function() {			
			this.wrapper 	=	$("<div class='homeMediaBoxWrapper' />")
			.css({
				display: "none",												
				borderBottomWidth: this.opts.borderWidth,
				borderBottomColor: this.opts.borderStart,
				borderBottomStyle: "solid",
				overflow: "hidden",
				position: "absolute",
				width: this.opts.width,
				zIndex: 100
			})
			.append(
				this.container 	= 	$("<div class='homeMediaBoxContainer' />").css({
					display: "none",
					height: this.opts.height
				}),
				this.closeBtn 	= 	$("<div class='boxClose' style='display: none;' />")
			).appendTo($("body"));
			
			$(this).trigger("box.build", [this.container, this.wrapper, this.closeBtn]);
			
			return this;
		},
		
		show: function() {						
			var self = this;
			
			$(window).bind("resize", this.position);
			this.position();			
			
			$(this).trigger("box.showstart", [this.container, this.wrapper, this.closeBtn])
			
			this.wrapper.show();
			this.wrapper.animate({
				borderBottomColor: this.opts.borderEnd
			}, 500);
			this.container.slideDown(500, function() {
				$(self).trigger("box.showend", [self.container, self.wrapper, self.closeBtn]);
			});
			
			return this;
		},
		
		hide: function() {
			var self = this;
			
			$(window).unbind("resize", this.position);
			
			$(this).trigger("box.hidestart", [this.container, this.wrapper, this.closeBtn])
						
			this.wrapper.animate({
				borderBottomColor: this.opts.borderStart
			}, 500);
			this.container.slideUp(500, function() {
				$(self).trigger("box.hideend", [self.container, self.wrapper, self.closeBtn]);
				self.wrapper.hide();
			});
			
			return this;
		},
		
		position: function() {			
			var offset = this.element.offset();
			this.wrapper.css({
				top: offset.top,
				left: offset.left - (this.opts.width - this.element.width())
			});		
		}
	};
		
})(jQuery);


// press release copy content
(function($) {
    // selectors for elements to remove from the copied content
    var excludedSelectors = ".exclude, .socialButtonList";
        
	$.codebuilder = (function() {
	
		var returned = function() {
			return this.initialize.apply(this, arguments);
		};
		
		returned.prototype = {
			defaults: {
				textSelector: "#formatAsText",
				htmlSelector: "#formatAsHTML",
				contentSelector: "#articleContent",
				embedContentSelector: "#embedContentBox",
				
				ajaxCloseSelector: "#embedBoxClose",
				ajaxHeadlineSelector: "h2",
				ajaxInputSelector: "textarea",
				
				htmlHeadline: "copy HTML",
				textHeadline: "copy text"
				
			},
			
			cleanHTML: "",
			cleanText: "",
			
			initialize: function(options) {
				var opts = this.opts = $.extend({}, this.defaults, options);
				this.btnTxt = $(opts.textSelector);
				this.btnHTML = $(opts.htmlSelector);
				this.content = $(opts.contentSelector);
				this.wrapper = $(opts.embedContentSelector).hide();
				
				this.closeBtn = null;
				this.headline = null;
				this.input = null;
				
				this.build();
			},
			
			build: function() {
				var clone = this.content.clone();					
				
				// remove excluded content				
				$(excludedSelectors, clone).remove();								
				
				// account for cufon
				var headline = clone.find("h1"),
					cufontext = headline.find("cufontext");
				
				if (headline) {
					headline.replaceWith($("<h1>" + headline.text() + "</h1>"));				
				}
				
				var els = clone.find("*");
				
				els.each(function(index, el) {
					el = $(el);
					if (el.attr("style") || el.attr("class")) {
						var replacement = $("<" + el.nodeName + " />").html(el.html());
						el.replaceWith(replacement);
					}
				});

				var cloneHTML = clone.html();
				this.cleanHTML = cloneHTML.replace(/^\s+|\s+$/g, '');
				this.cleanText = cloneHTML.replace(/(<[^>]*>)/g, "");
				this.cleanText = this.cleanText.replace(/^\s+|\s+$/g, '');//.replace(/\s+/g, ' ')
				
				
				$.ajax({
					url: window.root + "/js/config/copy_content.xml",
					cache: false,
					dataType: "xml",
					success: $.proxy(function(data, status, req) {
						var html = $("<div />").html($(data).find("html_content").text());
						
						this.closeBtn = html.find(this.opts.ajaxCloseSelector).bind("click", $.proxy(function() {
							this.close();
						}, this));
						
						this.headline = html.find(this.opts.ajaxHeadlineSelector);
						this.input = html.find(this.opts.ajaxInputSelector);
						
						html.appendTo(this.wrapper);
						this.attach();

					}, this)
				});
				
				return this;
			},
			
			attach: function() {
				this.btnTxt.bind("click", $.proxy(function() {
					this.show("text");
				}, this));
				this.btnHTML.bind("click", $.proxy(function() {
					this.show("html");
				}, this));			

				return this;
			},
			
			show: function(what) {
				var opts = this.opts;
				
				switch (what) {
					case "text":
						this.input.val(this.cleanText);
						this.headline.html(opts.textHeadline);
						break;
					case "html":
						this.input.val(this.cleanHTML);
						this.headline.html(opts.htmlHeadline);
						break;
				}
				
				try {
					Cufon.refresh();
				} catch(e) {}
				
				
				this.wrapper.show();
				this.input.focus().select();
				
				return this;
			},
			
			close: function() {
				this.wrapper.hide();
				
				return this;
			}			
		};
		
		
		return returned;
	})();
})(jQuery);

(function($) {
	this.ContactPods = {
		opts: {
			podSelector: ".locationPod",
			toggleSelector: ".directionToggle",
			closeSelector: ".locationPod .boxClose",
			contentSelector: ".directionsList"
		},
		
		init: function() {
			var opts = this.opts;
			this.pods = $(opts.podSelector);
			this.toggles = $(opts.toggleSelector);
			this.closes = $(opts.closeSelector);
			this.contents = $(opts.contentSelector);

			this.pods.each($.proxy(function(index, el) {
				el = $(el);
				var start = el.height(),
					end = $(this.contents[index]).innerHeight() + start;
				el.data("start-height", start);
				el.data("end-height", end);

			}, this));
			
			this.toggles.each($.proxy(function(index, el) {
				$(el).bind("click", $.proxy(function(e) {
					e.preventDefault();
					this.reveal(index);
				}, this));				
			}, this));
			
			this.closes.each($.proxy(function(index, el) {				
				$(el).bind("click", $.proxy(function(e) {
					e.preventDefault();
					this.hide(index);
				}, this));
			}, this));						
		},
		
		reveal: function(index) {
			var pod = $(this.pods[index]),
				end = pod.data("end-height")
				
				
			pod.animate(
				{
					"height": end
				},				
				$.proxy(function() {					
					$(this.closes[index]).show();
				}, this)
			);
		},
		
		hide: function(index) {
			var pod = $(this.pods[index]),
				start = pod.data("start-height")
			
			$(this.closes[index]).hide();
			pod.animate(
				{
					"height": start
				},
				function() {
					pod.css("height", "")
				}
			);		
		}
	
	}
})(jQuery);


