chat = function() {
	return {
	
		/***  VARIABLES  ***/
		baseUrl			: null,			// Set by PHP (Base URL)
		interval		: 30 * 1000,	// Interval between recieving last request and requesting a new one
		timerId			: null,			// Id of the interval timer
		checkTimerId	: null,
		listId			: null,			// Set by PHP (List ID)
		user			: {},			// Set by PHP (User Information)
		incoming		: {},			// Incoming Data
		moreinc			: {},			// More incoming data
		current			: {}, 			// Current Data
		lastRequest		: 0.0,			// Time of last request
		isUpdating		: true,			// Are we updating?
		isRequesting		: false,			// Are we updating?
		isActive		: {},			// Is this post active?
		isFollow		: {},			// Scroll with this post
		hosts			: {},			// Hosts Object
		limit			: 50,			// Number of posts to grab
		offset			: 1,			// Page of posts to grab
		
		postBuffer		: [],			// Store posts that need updating here
		isBuffered		: {},			// True if post is buffered
		newPosts		: 0,
		newUpdates		: 0,
		firstLoad		: true,
		
		
		/***  METHODS  ***/
		
		//Start Updating
		init: function() {
			chat.isUpdating = true;
			
			$("#joinChat").click(function(e) {
				e.preventDefault();
				
				if (circle.loggedin) {
					circle.joinCircle(chat.listId);
				} else {
					circle.showLoginBox();
				}
			});
			
			$("#editChat").click(function(e) {
				window.location = chat.baseUrl + "/editChat.php?l=" + chat.listId;
			});
			
			$("#startChat").click(function(e) {
				e.preventDefault();
				
				var params = {
					list : chat.listId,
					toggle : "true"
				};
				
				var url = chat.baseUrl + "/api/getPostsJson.php";

				$.getJSON(url, params, function(data) {
					chat.checkEnabled();
				});
			});
			
			$("#showMore").click(function(e) {
				e.preventDefault();
				
				chat.getMoreData();
			});
			
			chat.checkTimerId = setInterval(chat.checkEnabled, 120 * 1000);
			
			chat.getData();
		},
		
		checkEnabled: function() {
			var params = {
				list : chat.listId,
				check : "true"
			};
			
			var url = chat.baseUrl + "/api/getPostsJson.php";
			
			$.getJSON(url, params, function(data) {
				clearTimeout(chat.timerId);
				
				if (data == 1) {
					chat.isUpdating = true;
					chat.getData();
					
					//Update Page
					$("#postContentFrameContainer").css("display", "block");
					$("#chatActive").css("display", "none");
					$("#startChat").html("Stop Chat");
				} else {
					chat.isUpdating = false;
					
					$("#postContentFrameContainer").css("display", "none");
					$("#chatActive").css("display", "block");
					$("#startChat").html("Start Chat");
				}
			});
			
		}, 
		
		getMoreData: function() {
			var params = {
				list : chat.listId,
				limit : 50,
				offset : 50 * chat.offset
			};
			
			chat.offset++;
			chat.limit += 50;
			
			var url = chat.baseUrl + "/api/getPostsJson.php";
			
			$.getJSON(url, params, function(data) {
				if (data.error) {
					return;
				}
				
				chat.moreinc = data;
				chat.doMoreUpdate();
			});
		},
		
		doMoreUpdate: function() {
			var updates = chat.moreinc.updates;
			var count = chat.moreinc.count;
			
			jQuery.each(updates, function() {
				chat.addMorePost(this);
			});
			
			if (count > chat.limit) {
				$("#postMore").css("display", "block");
			} else {
				$("#postMore").css("display" , "none");
			}
		},
		
		//Retrieve incoming data
		getData: function() {
			if (!chat.isUpdating) {
				return;
			}
			
			if (chat.lastRequest == 0) {
				$("#postLoading").css("display", "block");
			}

			var params = {
				list : chat.listId,
				limit : chat.limit,
				min : chat.lastRequest
			};
			
			var date = new Date();
			//chat.lastRequest = Math.floor(date.getTime() / 1000);  //This needs to be in seconds
			//chat.lastRequest = date.getTime() / 1000;
			
			var url = chat.baseUrl + "/api/getPostsJson.php";

			$.getJSON(url, params, function(data) {
				if (data.error) {
					return;
				}
				
				chat.incoming = data;
				chat.lastRequest = data.now;
				
				chat.doUpdateList();
			});
		},
		
		showNewPosts: function() {
			chat.newPosts = 0;
			chat.newUpdates = 0;
			
			$("#postNew").css("display", "none");
			
			while (chat.postBuffer.length > 0) {
				var post = chat.postBuffer.shift();
				delete chat.isBuffered[post.id];
				
				if (chat.current[post.id]) {
					chat.updatePost(post);
				} else {
					chat.addNewPost(post);
				}
			}
		},
		
		//Update current data from incoming data
		doUpdateList: function() {
			
			var enabled = chat.incoming.enabled;
			var posts = chat.incoming.posts;
			var updates = chat.incoming.updates;
			var count = chat.incoming.count;
			
			/*
				Check that chat is still active
			*/
			if (enabled == 1) {
				clearTimeout(chat.timerId);
				chat.timerId = setTimeout(chat.getData, chat.interval);
			} else {
				chat.checkEnabled();
			}
			
			/*
				Remove any old posts
			*/
			jQuery.each(chat.current, function() {
				var result = jQuery.inArray(this.id, posts)
				if (result == -1) {
					chat.removeOldPost(this.id);
				}
			});
			
			/*
				Add new/Update old posts  (If they aren't in the do not update list)
			*/
			jQuery.each(updates, function() {
				
				if (!chat.isBuffered[this.id]) {
					if (chat.current[this.id]) {
						chat.newUpdates++;
					} else {
						if (this.duid == chat.user.duid  && !chat.firstLoad) {
							chat.addNewPost(this);
							return true;
						}
						
						chat.newPosts++
					}
				} else {
					for (var i=0; i<chat.postBuffer.length; i++) {
						if (this.id = chat.postBuffer[i].id) { chat.postBuffer.splice(i, 1); }
					}
				}
				
				chat.isBuffered[this.id] = true;
				chat.postBuffer.push(this);
			});
			
			if ((chat.newUpdates + chat.newPosts) == 50  || chat.firstLoad) {
				chat.firstLoad = false;
				chat.showNewPosts();
			} else if (chat.newUpdates > 0 || chat.newPosts > 0) {
				$("#postNew").css("display", "block");
				
				var newHtml = "";
				
				if (chat.newPosts > 0) {
					newHtml += "SHOW " + chat.newPosts + " NEW POST" + (chat.newPosts == 1 ? " " : "S ");
				}
				if (chat.newUpdates > 0) {
					if (chat.newPosts > 0) {
						newHtml += "AND ";
					} else {
						newHtml += "SHOW ";
					}
					newHtml += chat.newUpdates + " UPDATED POST" + (chat.newUpdates == 1 ? " " : "S ");
				}
				
				$("#postNew a").html(newHtml);
			}
			
			
			//Follow a post if it's being commented on?
			
			/*  Disable Following
			var isActive = $(".isActive").get(0);
			if (isActive) {
				var activeId = $(isActive).attr("id").replace("comment_text_","");
				if (!isNaN(activeId)) {
					var activePost = chat.current[activeId];
					$.scrollTo(activePost.div, 1000, {offset: {top: -120, left: 0}});
				}
			}
			*/
			
			
			//Remove loading graphic
			$("#postLoading").css("display", "none");
			
			if (count > chat.limit) {
				$("#postMore").css("display", "block");
			} else {
				$("#postMore").css("display" , "none");
			}
			
			//Update the circle controls (adding comments etc...)
			circle.initControls();
		},
		
		//Remove post (id) from the current data
		removeOldPost: function(id) {
			$(chat.current[id].div).remove();
			$(chat.current[id].divider).remove();
			delete chat.current[id];
		},
		
		//Update post in current data
		updatePost: function(post) {
			/*
				TODO	New comments is the only reason a post would be updated
			*/
			oldPost = chat.current[post.id];
			
			post.div = oldPost.div;
			post.divider = oldPost.divider;
			
			chat.current[post.id] = post;
			
			if (post.comments) {
				var cContentBlockDiv = $("#item_"+post.id+" .postedContentCommentBlock");
			
				if (cContentBlockDiv.length == 0) {
					//Build comments area
					var cHeaderDiv = $("<div/>").addClass("postedContentComments").css("font-weight", "bold").html("Comments:");
						cHeaderDiv.insertBefore("#actions_" + post.id);
				
					cContentBlockDiv = $("<div/>").addClass("postedContentCommentBlock");
						cContentBlockDiv.insertBefore("#actions_" + post.id);
				}
			
				//Empty current comments
				cContentBlockDiv.empty();
			
				var cHiddenBlockDiv = $(".hiddenCommentBlock_" + post.id);
				if (post.comments.length > 5 && cHiddenBlockDiv.length == 0) {
					cHiddenBlockDiv = $("<div/>").addClass("hiddenCommentBlock_" + post.id).css("display", "none");
					cHiddenBlockDiv.insertBefore("#actions_" + post.id);
					var cShowMoreDiv = $("<div/>").addClass("postedContentShowMoreComments").append($("<a/>").attr("href", "#").click(function(e) {
							e.preventDefault();
					
							var cHBlock = $(".hiddenCommentBlock_" + post.id);
							if (cHBlock.css('display') == "none") {
								$(e.target).html("Hide extra comments");
							} else {
								$(e.target).html("Show all comments");
							}
							cHBlock.slideToggle(600);
						}).html("Show all comments")).insertBefore("#actions_" + post.id);
				
				}
				
				//Empty hidden comments
				cHiddenBlockDiv.empty();
			
				for (var i=0; i < post.comments.length; i++) {
					var	comment = post.comments[i];
					
					var cContentDiv = $("<div/>").addClass("postedContentComment clearfix");
					if (i < 5) {
						cContentBlockDiv.append(cContentDiv);
					} else {
						cHiddenBlockDiv.append(cContentDiv);
					}
					
					var cHeadIconDiv = $("<div/>").addClass("commentHeadIcon").append($("<a/>").attr("href", "/profile.php?u=" + comment.duid).append($("<img/>").addClass("postThumb").attr("src", comment.user_thumb).css("width", "16px")));
					cContentDiv.append(cHeadIconDiv);
					
					var cContentBodyDiv = $("<div/>").addClass("commentContentBody").html('" ' + comment.description + ' " ');
					var cDateSpan = $("<span/>").css("color", "#48453E").html(chat.prettyTime(comment.created * 1000) + " ").appendTo(cContentBodyDiv);
					var cCommenter = $("<a/>").attr("href", "/profile.php?u=" + comment.duid).html(comment.display_name).appendTo(cContentBodyDiv);
					for (var host in chat.hosts) {
						if (chat.hosts[host].duid == comment.duid) { cCommenter.css("color", "#2F53FF").prepend("<span style='font-weight: normal'>host: </span>"); }
					}
					
					cContentDiv.append(cContentBodyDiv);
				}
			}
			
			
			$("#postList").prepend(post.divider);
			$("#postList").prepend(post.div);
			
			/*  Disable Following
			if (chat.isFollow[post.id]) {
				$.scrollTo(post.div, 1000, {offset: {top: -120, left: 0}});
				delete chat.isFollow[post.id];
			}
			*/
		},
		
		//Add post to the current data
		addNewPost: function(post) {
			var postDiv = chat.formatPost(post);
			
			post.div = postDiv;
			chat.current[post.id] = post;
			
			post.divider = $("<div/>").addClass("postDivider clearfix").get(0);
			
			$("#postList").prepend(post.divider);
			$("#postList").prepend(post.div);
		},
		
		addMorePost: function(post) {
			var postDiv = chat.formatPost(post);
			
			post.div = postDiv;
			chat.current[post.id] = post;
			
			post.divider = $("<div/>").addClass("postDivider clearfix").get(0);
			
			$("#postList").append(post.divider);
			$("#postList").append(post.div);
		}, 
		
		//Return a properly formatted div for a post
		formatPost: function(post) {
			
			var mainDiv = $("<div/>").addClass("postedItem clearfix " + post.type_name).attr("id", "item_" + post.id);
			
			var postIcon, postAction, postExtraDiv;
			switch (post.type_name) {
				case "image":
					postIcon = "/images/famfam/photoposted.png";
					if (post.image_thumb) {
						postExtraDiv = $("<div/>").addClass("postedContentImageContainer").append($("<div/>").addClass("imageIcon").append($("<img/>").attr("src", post.image_thumb)));
							postExtraDiv.append($("<div/>").addClass("imageShow").append($("<img/>").attr("src", post.image)));
					} else {
						postExtraDiv = $("<div/>").addClass("postedContentImageContainer").append($("<div/>").addClass("imageShow").css("display", "block").append($("<img/>").attr("src", post.image)));
					}
					postAction = "photo";
					break;
				case "video":
					postIcon = "/images/famfam/videoposted.png";
					postExtraDiv = $("<div/>").addClass("postedContentVideoContainer").append($("<div/>").addClass("videoIcon").click(function() { chat.isFollow[post.id]; }).append($("<img/>").attr("src", post.video_thumb)));
						postExtraDiv.append($("<div/>").addClass("videoShow").html(post.video));
					postAction = "video";
					break;
				case "audio":
					postIcon = "/images/famfam/soundposted.png";
					postExtraDiv = $("<div/>").addClass("audioShow").html(post.audio);
					postAction = "sound";
					break;
				case "link":
					postIcon = "/images/famfam/linkposted.png";
					postAction = "link";
					break;
				case "quote":
					postIcon = "/images/famfam/quoteposted.png";
					postAction = "quote";
					break;
				case "text_note":
					postIcon = "/images/famfam/noteposted.png";
					postAction = "note";
					break;
				case "text":
					postIcon = "/images/famfam/storyposted.png";
					postAction = "story";
					break;
				default:
					postIcon = "/images/famfam/noteposted.png";
					break;
			}
			
			/*
				TODO 	Video Icon and Image Thumbnail
			*/
			
			var iconDiv = $("<div/>").addClass("postedTypeIcon").append($("<img/>").attr("src", postIcon));
			mainDiv.append(iconDiv);
			
			var contentWrapDiv = $("<div/>").addClass("postedContentBodyWrap");
			mainDiv.append(contentWrapDiv);
			
			
			if (!post.user_thumb) {
				post.user_thumb = "/images/MotherhoodAvatar.png";
			}
			
			var userThumb = $("<a/>").attr("href", "/profile.php?u=" + post.duid).append($("<img/>").addClass("postThumb").attr("src", post.user_thumb).css("width", "16px"));
			var dateSpan = $("<span/>").html(chat.prettyTime(post.created * 1000) + " ");
			var userName = $("<a/>").attr("href", "/profile.php?u=" + post.duid).css("font-weight", "bold").html(post.display_name);
			for (var host in chat.hosts) {
				if (chat.hosts[host].duid == post.duid) { userName.css("color", "#2F53FF").prepend("<span style='font-weight: normal'>host: </span>"); }
			}
			
			var actionSpan = $("<span/>").html(" posted a " + postAction);
			var actionDiv = $("<div/>").addClass("postedAction").append(userThumb).append(dateSpan).append(userName).append(actionSpan);
			
			contentWrapDiv.append(actionDiv);
			
			if (postExtraDiv) {
				contentWrapDiv.append(postExtraDiv);
			}
			
			var titleDiv = $("<div/>").addClass("postedContentTitle").append($("<a/>").attr("href", "/post.php?sid=" + post.id).html(post.name));
			contentWrapDiv.append(titleDiv);
			
			var textDiv = $("<div/>").addClass("postedContentText").html(post.description);
			contentWrapDiv.append(textDiv);
			
			//Comments
			if (post.comments) {
				var cHeaderDiv = $("<div/>").addClass("postedContentComments").css("font-weight", "bold").html("Comments:");
				contentWrapDiv.append(cHeaderDiv);
				
				var cContentBlockDiv = $("<div/>").addClass("postedContentCommentBlock");
				contentWrapDiv.append(cContentBlockDiv);
				
				var cHiddenBlockDiv;
				if (post.comments.length > 5) {
					cHiddenBlockDiv = $("<div/>").addClass("hiddenCommentBlock_" + post.id).css("display", "none");
					contentWrapDiv.append(cHiddenBlockDiv);
					var cShowMoreDiv = $("<div/>").addClass("postedContentShowMoreComments").append($("<a/>").attr("href", "#").click(function(e) {
							e.preventDefault();
						
							var cHBlock = $(".hiddenCommentBlock_" + post.id);
							if (cHBlock.css('display') == "none") {
								$(e.target).html("Hide extra comments");
							} else {
								$(e.target).html("Show all comments");
							}
							cHBlock.slideToggle(600);
						}).html("Show all comments")).appendTo(contentWrapDiv);
					
				}
				
				for (var i=0; i < post.comments.length; i++) {
					var	comment = post.comments[i];
					
					var cContentDiv = $("<div/>").addClass("postedContentComment clearfix");
					if (i < 5) {
						cContentBlockDiv.append(cContentDiv);
					} else {
						cHiddenBlockDiv.append(cContentDiv);
					}
					
					var cHeadIconDiv = $("<div/>").addClass("commentHeadIcon").append($("<a/>").attr("href", "/profile.php?u=" + comment.duid).append($("<img/>").addClass("postThumb").attr("src", comment.user_thumb).css("width", "16px")));
					cContentDiv.append(cHeadIconDiv);
					
					var cContentBodyDiv = $("<div/>").addClass("commentContentBody").html('" ' + comment.description + ' " ');
					var cDateSpan = $("<span/>").css("color", "#48453E").html(chat.prettyTime(comment.created * 1000) + " ").appendTo(cContentBodyDiv);
					var cCommenter = $("<a/>").attr("href", "/profile.php?u=" + comment.duid).html(comment.display_name).appendTo(cContentBodyDiv);
					for (var host in chat.hosts) {
						if (chat.hosts[host].duid == comment.duid) { cCommenter.css("color", "#2F53FF").prepend("<span style='font-weight: normal'>host: </span>"); }
					}
					
					cContentDiv.append(cContentBodyDiv);
				}
			}
			
			var postActionDiv = $("<div/>").addClass("postedContentActionBlock clearfix").attr("id", "actions_" + post.id);
			contentWrapDiv.append(postActionDiv);
			
			var postCommentSpan = $("<span/>").addClass("postedContentAction postAddComment").html("Add a comment");
				/*
				postCommentSpan.click(function() {
					if (chat.isActive[post.id]) {
						delete chat.isActive[post.id];
					} else {
						chat.isActive[post.id] = true;
					}
				});
				*/
			postActionDiv.append(postCommentSpan);
			
			var postTagSpan = $("<span/>").addClass("postedContentAction postAddTag").html("<a id=postTag_" + post.id + "href='javascript:circle.showWordTag(" + post.id + ");'>Add a tag</a>");
			postActionDiv.append(postTagSpan);
			
			if (post.type_name !== "link") {
				var postReblogSpan = $("<span/>").addClass("postedContentAction postReBlog").html("<a href='javascript:circle.reblogStory(" + post.id + "," + escape(post.title) + ");'>ReBlog</a>");
				postActionDiv.append(postReblogSpan);
			}
			
			//Twitter
			var twitterLink = chat.baseUrl + "/post.php?sid=" + post.id;
			var twitterTitleLength = 140 - 4 - twitterLink.length;
			var twitterTitle = post.name;
			if (twitterTitle.length > twitterTitleLength) {
				twitterTitle = twitterTitle.substr(0, twitterTitleLength - 3);
				twitterTitle += "...";
			}
			var twitterStatus = twitterTitle + " - " + twitterLink;
			
			var postTwitterSpan = $("<span/>").addClass("postedContentAction postTwitterThis");
				postTwitterSpan.append($("<a/>").attr("href", "http://twitter.com/home?status=" + escape(twitterStatus)).html("Twitter This"));
			postActionDiv.append(postTwitterSpan);
			
			
			//Administration
			var postEditor = (chat.user.duid == post.duid);
			if (postEditor || chat.user.listEditor) {
				// Edit and Remove Post
				var editSpan = $("<span/>").addClass("postedContentAction postEdit").html($("<a/>").attr("href", "/edit.php?sid=" + post.id).html("Edit"));
				var removeSpan = $("<span/>").addClass("postedContentAction postRemove").html($("<a/>").attr("href", "javascript:circle.deletePost(" + post.id + ")").html("Remove"));
				postActionDiv.append(editSpan).append(removeSpan);
			}
			
			/***  Circle Administration (Needed?)
			if (chat.user.listEditor || chat.user.superUser) {
				var adminDropDownSpan = $("<span/>").addClass("itemDropDownControl").attr("id", "itemDropDown_" + post.id);
					adminDropDownSpan.append($("<span/>").addClass("dropDownImg").attr("id", "dropDownImg_" + post.id).html("Admin Options <img src='/images/v3/dropdown.png' style='vertical-align: middle;' />"));
				var adminDropDownDiv = $("<div/>").addClass("dropDownEditMenu").attr("id", "dropDownEditMenu_" + post.id);
				var adminDropDownList = $("<ul/>").addClass("editMenuUL");
			}
			***/
			
			//Hidden Divs for Commenting/Tagging
			var hiddenCommentDiv = $("<div/>").addClass("commentWrap clearfix").attr("id", "addComment_input_" + post.id);
				hiddenCommentDiv.append($("<textarea/>").attr("id", "comment_text_" + post.id)
												.focus(function() {
													$(this).addClass("isActive");
													chat.isActive[post.id] = true;
												})
												.blur(function() {
													$(this).removeClass("isActive");
													delete chat.isActive[post.id];
												})
											);
			var commentActionInputs = $("<div/>").addClass("actionInputActions");
			var commentActionSubmit = $("<div/>").addClass("actionInputSubmit").css("margin-right", "3px");
				commentActionSubmit.append($("<a/>").click(function() { 
						circle.submitComment(post.id, post.pheed, chat.user.duid, chat.user.display_name, chat.user.thumb);
						//delete chat.isActive[post.id];  (Don't need this since closing the box will do it);
						chat.isFollow[post.id] = true;
					}).html("Post"));
			var commentActionCancel = $("<div/>").addClass("actionInputCancel");
				commentActionCancel.append($("<a/>").click(function() { 
						circle.cancelComment(post.id);
						//delete chat.isActive[post.id];
					}).html("Cancel"));
			commentActionInputs.append(commentActionSubmit).append(commentActionCancel);
			hiddenCommentDiv.append(commentActionInputs);
			
			contentWrapDiv.append(hiddenCommentDiv);
			
			return mainDiv.get(0);
		},
		
		//Return the current time formatted (Ex. 12:00pm)
		prettyTime: function(date) {
			var theDate = new Date(date);
			
			var ap = "am";
			var hour = theDate.getHours();
			if (hour   > 11) { ap = "pm"; }
			if (hour   > 12) { hour = hour - 12; }
			if (hour   == 0) { hour = 12; }
			
			var min = theDate.getMinutes();
			min = min + "";
			
			if (min.length == 1) {
				min = "0" + min;
			}
			
			return hour + ":" + min + "" + ap;
		}
		
	};
}();