/*	
.-------------------------------------------------------------------------.
|                                                                         |
|  AUTHORS' UNIVERSE                                                      |
|  JS Framework                                                           |
|  ---------------------------------------------------------------------  |
|  Provides the singleton containing supplemental methods and properties  |
|  for various portions of the site.                                      |
|                                                                         |
'-------------------------------------------------------------------------'
*/	
var framework = {
	prop: {
		pageID: "", 
		overlayTimer: 0, 
		overlayVisible: false
	},
	global: {
		fn: {
			clearValidatorCallouts:
				function() { 
					// custom .NET page validator display functions
					
					var intCounter;
					var arrInvalidControls = [];
					
					for (intCounter = 0; intCounter < Page_Validators.length; intCounter++) {
						var objElement = jQuery("#" + Page_Validators[intCounter].controltovalidate);

						// special case test for telerik datepicker control
						if ((jQuery(objElement).hasClass("rdfd_")) && (jQuery(objElement).css("visibility") == "hidden") && (jQuery(objElement).siblings("table").length > 0)) {
							objElement		= jQuery(objElement).siblings("table").find("input.riTextBox");
						}
						
						if (typeof(objElement) == "object") {
							$(objElement).removeClass("error");
						}
					}
				}, 
				
			setValidatorCallouts: 
				function() { 
					// custom .NET page validator display functions
					var intCounter;
					var boolPageValid = true;
					
					for (intCounter = 0; intCounter < Page_Validators.length; intCounter++) {
						var objElement = jQuery("#" + Page_Validators[intCounter].controltovalidate);
						
						// special case test for telerik datepicker control
						if ((jQuery(objElement).hasClass("rdfd_")) && (jQuery(objElement).css("visibility") == "hidden") && (jQuery(objElement).siblings("table").length > 0)) {
							objElement		= jQuery(objElement).siblings("table").find("input.riTextBox");
						}
						
						if (typeof(objElement) == "object") {
							if (!Page_Validators[intCounter].isvalid) {
								if (boolPageValid) {
									jQuery(objElement).focus();
								}
								
								if (!jQuery(objElement).hasClass("error")) {
									jQuery(objElement).addClass("error");
								}
								
								boolPageValid	= false;
							}
						}
					}
					
					return boolPageValid;
				}, 
				
			scrollToTop: 
				function() {
					jQuery("html, body")
						.animate(	{"scrollTop": 0}, 
									1500, 
									"easeOutExpo");
				}, 
				
			showLoadingOverlay: 
				function() {
					clearTimeout(framework.prop.overlayTimer);
					
					if (!framework.prop.overlayVisible) {
						framework.prop.overlayVisible	= true;
						
						var dblContentWidth				= jQuery("#content-area>.frame").width();
						var dblContentXOffset			= 5; //Math.abs(jQuery("#content-loading-overlay>#content-loading").position().left);
						var dblContentHeight			= jQuery("#content-area").height() - jQuery("#content-area>.header").height() + (jQuery("#content-loading-overlay>#content-loading").position().top);
						var dblContentYOffset			= 13; //Math.abs(jQuery("#content-loading-overlay>#content-loading").position().top);
						
						jQuery("#content-loading-overlay>#content-loading")
							.css({"width": (dblContentWidth + (dblContentXOffset * 2)) + "px", "height": ((dblContentHeight * 2) + dblContentYOffset) + "px"})
							.find("ins")
								.css({"opacity": 0});
						jQuery("#content-loading-overlay")
							.css({"opacity": 0, "display": "block"})
							.animate(	{"opacity": 1}, 
										500, 
										"easeOutQuad", 
										function() { 
											var dblLoaderWidth		= jQuery("#content-loading-overlay>#content-loading>ins").width();
											var dblLoaderHeight		= jQuery("#content-loading-overlay>#content-loading>ins").height();
											var dblLoaderLeft		= ((dblContentWidth - dblLoaderWidth) / 2);
											var dblLoaderTop		= ((dblContentHeight - dblLoaderHeight) / 4);
											
											jQuery("#content-loading-overlay>#content-loading>ins")
												.css({"marginTop": dblLoaderTop + "px", "marginLeft": dblLoaderLeft + "px"});
											jQuery("#content-loading-overlay>#content-loading>ins")
												.animate({"opacity": 1}, 500, "easeOutQuad");
										});
					}
				}, 
				
			hideLoadingOverlay:
				function() {
					clearTimeout(framework.prop.overlayTimer);
					
					framework.prop.overlayTimer		= setTimeout(	function() { 
																		jQuery("#content-loading-overlay")
																			.fadeOut(	function() { 
																							jQuery("#content-loading-overlay").css({"display": "none"}); 
																						});
																	}, 500);
					framework.prop.overlayVisible	= false;
				}, 
				
			replaceCheckboxes: 
				function() {
					var objElements			= jQuery("input.input[type=checkbox], span.input>input[type=checkbox]");
					var objElement;
					var strCheckboxName		= "";
					var boolMSIE			= ((navigator.userAgent.indexOf("MSIE") > -1) ? true : false);
					var boolChecked			= false;
					
					if ((objElements) && (objElements.length)) {
						for (var intCounter = 0; intCounter < objElements.length; intCounter++) {
							strCheckboxName			= jQuery(objElements[intCounter]).attr("id");
							
							if ((strCheckboxName) && (strCheckboxName.length)) {
								objElement				= jQuery("input#" + strCheckboxName);
								boolChecked				= ((jQuery("input#" + strCheckboxName + ":checked").length) ? true : false);
								
								// hide the <input> container from view and add in dummy styled container
								// set up events
								if (boolMSIE) {
									// SUPER FUN INTERNET EXPLODER WORKAROUNDS SINCE CHECKBOXES DON'T FIRE OFF CHANGE EVENTS WHEN HIDDEN!
									jQuery(objElement)
										.hide()
										.before("<a href=\"javascript:;\" rel=\"" + strCheckboxName + "\" class=\"checkbox" + ((boolChecked) ? " selected" : "") + "\">&nbsp;</a>");
									
									jQuery(objElement)
										.bind("change", framework.global.fn.handleCheckbox);
												
									jQuery("a[rel=" + strCheckboxName + "]")
										.bind(	"click", 
												function() { 
													var objInputElement		= jQuery("input#" + jQuery(this).attr("rel"));
													
													if (jQuery(objInputElement).attr("checked")) {
														jQuery(objInputElement).attr("checked", false);
													} else {
														jQuery(objInputElement).attr("checked", true);
													}
													
													jQuery(objInputElement).trigger("change");
												});
									jQuery("label[for=" + strCheckboxName + "]")
										.bind(	"click", 
												function() { 
													var objInputElement		= jQuery("input#" + jQuery(this).attr("for"));
													
													if (jQuery(objInputElement).attr("checked")) {
														jQuery(objInputElement).attr("checked", false);
													} else {
														jQuery(objInputElement).attr("checked", true);
													}
													
													jQuery(objInputElement).trigger("change");
												});
								} else {
									jQuery(objElement)
										.hide()
										.before("<a href=\"javascript:;\" rel=\"" + strCheckboxName + "\" class=\"checkbox" + ((boolChecked) ? " selected" : "") + "\">&nbsp;</a>")
										.bind("change", framework.global.fn.handleCheckbox);
									
									jQuery("a[rel=" + strCheckboxName + "]")
										.bind("click", framework.global.fn.toggleCheckbox);
										
								}
								
								if (boolChecked) {
									jQuery("label[for='" + strCheckboxName + "']")
										.addClass("active");
								}
							}
						}
					}
				}, 
				
			handleCheckbox: 
				function(objEvent) {
					if ((objEvent) && (objEvent.currentTarget)) {
						var objElement			= jQuery(objEvent.currentTarget);
						var strCheckboxName		= jQuery(objElement).attr("id");
						
						if ((strCheckboxName) && (strCheckboxName.length)) {
							var objWrapper			= jQuery("a[rel=" + strCheckboxName + "]");
							var objLabel			= jQuery("label[for='" + strCheckboxName + "']");
							var boolChecked			= ((jQuery("input#" + strCheckboxName + ":checked").length) ? true : false);
							
							if (objWrapper) {
								if ((boolChecked) && (!jQuery(objWrapper).hasClass("selected"))) {
									jQuery(objWrapper).addClass("selected");
									
									if (typeof(objLabel) == "object") {
										if (!jQuery(objLabel).hasClass("active")) {
											jQuery(objLabel).addClass("active");
										}
									}
								} else if (jQuery(objWrapper).hasClass("selected")) {
									jQuery(objWrapper).removeClass("selected");

									if (typeof(objLabel) == "object") {
										if (jQuery(objLabel).hasClass("active")) {
											jQuery(objLabel).removeClass("active");
										}
									}
								}
							}
						}
					}
				}, 
				
			toggleCheckbox: 
				function(objEvent) {
					if ((objEvent) && (objEvent.currentTarget)) {
						var objWrapper			= jQuery(objEvent.currentTarget);
						var strCheckboxName		= jQuery(objWrapper).attr("rel");
						
						if ((strCheckboxName) && (strCheckboxName.length)) {
							var objElement			= jQuery("input#" + strCheckboxName);
							var objLabel			= jQuery("label[for='" + strCheckboxName + "']");
							var boolChecked			= ((jQuery("input#" + strCheckboxName + ":checked").length) ? true : false);
							
							if (objElement) {
								if (boolChecked) {
									jQuery(objElement).attr("checked", false).trigger("change");
									
									if (jQuery(objWrapper).hasClass("selected")) {
										jQuery(objWrapper).removeClass("selected");
									}
									
									if (typeof(objLabel) == "object") {
										if (jQuery(objLabel).hasClass("active")) {
											jQuery(objLabel).removeClass("active");
										}
									}
								} else { 
									jQuery(objElement).attr("checked", true).trigger("change");
									
									if (!jQuery(objWrapper).hasClass("selected")) {
										jQuery(objWrapper).addClass("selected");
									}
									
									if (typeof(objLabel) == "object") {
										if (!jQuery(objLabel).hasClass("active")) {
											jQuery(objLabel).addClass("active");
										}
									}
								}
							}
						}
					}
				}
		}
	}, 
	journalProperties: {
		prop: {
			defaultJournalClientID: "", 
			mainScrollContainer: null, 
			draftScrollContainers: [], 
			draftWidth: 0, 
			draftMarginLeft: 0, 
			draftMarginRight: 0, 
			draftMargins: 0
		}, 
		fn: {
			setContainerSize:
				function() {
					// this method sets the width of the scrolling container containing all of the journal "tiles".  this is required to achieve a horizontally-scrolling container -- otherwise, the container would scroll vertically
					
					var objJournals			= jQuery("#journals-inner>ul>li");
					var objFirstElement		= jQuery("#journals-inner>ul>li:first");
					var dblItemWidth		= parseFloat(jQuery(objFirstElement).width());
					var dblMarginLeft		= parseFloat(jQuery(objFirstElement).css("marginLeft").replace("px", ""));
					var dblMarginRight		= parseFloat(jQuery(objFirstElement).css("marginRight").replace("px", ""));
					var dblMargins			= (dblMarginLeft + dblMarginRight);
					
					dblItemWidth			+= (dblMargins * 2);
					
					jQuery("#journals-inner").css("width", (dblItemWidth * objJournals.length) + "px");
				}, 

			setDraftContainerSize:
				function(objContainer) {
					var objDrafts											= jQuery(objContainer).find("li");		// find each <li> inside the drafts container.  this will give us a list of how many drafts there are.
					
					if (framework.journalProperties.prop.draftWidth == 0) {
						framework.journalProperties.prop.draftWidth				= parseFloat(jQuery(objDrafts[0]).width());									// calculate the width of the first draft <li>
						framework.journalProperties.prop.draftMarginLeft		= parseFloat(jQuery(objDrafts[0]).css("marginLeft").replace("px", ""));		// calculate the left margin
						framework.journalProperties.prop.draftMarginRight		= parseFloat(jQuery(objDrafts[0]).css("marginRight").replace("px", ""));	// calculate the right margin
						
						// calculate the sum of the two margins
						framework.journalProperties.prop.draftMargins			= (framework.journalProperties.prop.draftMarginLeft + framework.journalProperties.prop.draftMarginRight);
						
						// save the width of the <li> including the margin widths
						framework.journalProperties.prop.draftWidth				+= (framework.journalProperties.prop.draftMargins * 2);
					}
					
					// set the width on the parent <div class="drafts-inner"> container.
					if (objDrafts.length > 0) {
						jQuery(objContainer).parents(".drafts").css("visibility", "visible");
					}
					
					jQuery(objContainer).parents(".drafts-inner").css("width", (framework.journalProperties.prop.draftWidth * objDrafts.length) + "px");
				}, 
			
			showConfirmationDialog:
				function(strActionType, objContainer) {
					switch (strActionType.toLowerCase()) {
						case "journal" : 
							// set the warning text
							jQuery("#journals-confirmation>blockquote>strong").html("Are you sure you want to delete this journal?");

							// set on-click bindings for the "yes" button to perform actions related to deleting a journal
							jQuery("#journals-confirmation>blockquote>a.yes")
								.unbind("click")
								.bind(	"click", 
										function() { 
											framework.journalProperties.fn.deleteJournal(objContainer); 
										});
							break;
							
						case "draft" : 
							// set the warning text
							jQuery("#journals-confirmation>blockquote>strong").html("Are you sure you want to delete this draft?");
							
							// set on-click bindings for the "yes" button to perform actions related to deleting a draft
							jQuery("#journals-confirmation>blockquote>a.yes")
								.unbind("click")
								.bind(	"click", 
										function() { 
											framework.journalProperties.fn.deleteDraft(objContainer);
										});
							break;
					}
					
					jQuery("#journals-confirmation").show();
				}, 
				
			hideConfirmationDialog:
				function() {
					jQuery("#journals-confirmation").hide();
				}, 
				
			editJournalTitle: 
				function() {
					// hide the <strong> tag calling this method
					jQuery(this)
						.css("visibility", "hidden");
						
					// hide the <ol> element that houses all of the checkboxes and auto-save items so that the user doesn't inadvertently click on them while editing their journal title
					jQuery(this)
						.siblings("ol")
						.css("visibility", "hidden");
						
					// show the <textarea> so the user can start editing the title, and set the value of the <textarea> to what the <strong> tag calling this method contains in it's innerHTML
					jQuery(this)
						.siblings("textarea")
						.html(jQuery(this).html())
						.css("display", "block")
						.focus();
				}, 
				
			updateJournalTitle:
				function() {
					var intJournalID	= parseInt(jQuery(this).siblings("input[type=hidden]:first").val());		// grab first <input type="hidden"> at the same nesting level
					var strNewTitle		= jQuery(this).val();														// grab the value of the <textarea> calling this method (from the "blur" event)
					
					if ((!isNaN(intJournalID)) && (intJournalID > 0) && (strNewTitle.length)) {
						// journal ID is numeric, non-zero, and new title is not blank, so let's go

						// remove any newlines from the title, since we never want newlines in the title
						strNewTitle			= strNewTitle.replace(/\r|\n/gi, " ");
						
						// hide the <textarea> calling this method
						jQuery(this)
							.css("display", "none");
							
						// show the checkbox and auto-save items by showing the <ol> element housing all of them
						jQuery(this)
							.siblings("ol")
							.css("display", "block")
							.css("visibility", "visible");
							
						// show the <strong> tag that houses the journal title normally, and set the innerHTML of it to what the user typed in inside the <textarea>
						jQuery(this)
							.siblings("strong")
							.html(strNewTitle)
							.css("display", "block")
							.css("visibility", "visible");
							
						// set the title via AJAX
						jQuery.ajax({
										type: "POST", 
										contentType: "application/json; charset=utf-8", 
										url: "JournalProperties.aspx/UpdateJournalPreferences", 
										data: '{JournalID: "' + intJournalID.toString() + '", PreferenceType: "journalname", PreferenceValue: "' + strNewTitle + '"}', 
										dataType: "json", 
										success: function(objResult) {}, 
										error: function(objResult) {}
									});
					}
				}, 
				
			setDefaultJournal:
				function() {
					var intDefaultJournalID		= parseInt(jQuery(this).val());		// get the selected journal id from the dropdown box's value.
					
					if ((!isNaN(intDefaultJournalID)) && (intDefaultJournalID > 0)) {
						// new default journal id from the dropdown is numeric and greater than zero, so let's proceed
						jQuery.ajax({
										type: "POST", 
										contentType: "application/json; charset=utf-8", 
										url: "JournalProperties.aspx/SetDefaultJournal", 
										data: '{JournalID: "' + intDefaultJournalID.toString() + '"}', 
										dataType: "json", 
										success: function(objResult) {}, 
										error: function(objResult) {}
									});
					}
				}, 
				
			deleteJournal: 
				function(objContainer) {
					// this method handles removing a journal "tile" from the page, and upon removal, re-initializes some key page elements such as the scroll container.
					
					// grab the journal id from the <input type="hidden"> next to this <a> element at the same nesting level (thus, it's a "sibling")
					var intJournalID			= parseInt(jQuery(objContainer).siblings("input[type=hidden]").val());	
					
					if ((!isNaN(intJournalID)) && (intJournalID > 0)) {
						var objParentContainer		= jQuery(objContainer).parents("li");					// target the <li> that houses all of the information for this particular journal tile
						
						jQuery(objParentContainer)
							.fadeOut(	function() { 
											// this function runs after the fadeout is complete
											
											jQuery(this).remove(); 												// remove the <li> item we just faded out from the page
											
											framework.journalProperties.fn.setContainerSize();					// resize the container housing all of the tiles
											
											var objJournals				= jQuery("#journals-inner>ul>li");		// get a list of all the journals tiles remaining
											
											if (objJournals.length >= 4) {
												if (typeof(framework.journalProperties.prop.mainScrollContainer) == "object") {
													framework.journalProperties.prop.mainScrollContainer.reinitialise();		// reinitialize the jScrollPane scrollbar
												}
											} else {
												jQuery("#journals").addClass("single-line");									// add single line class since we're under 4 journals now
												
												if (typeof(framework.journalProperties.prop.mainScrollContainer) == "object") {
													framework.journalProperties.prop.mainScrollContainer.destroy();				// remove the scrollbar container since we don't need it anymore
												}
											}
											
											framework.journalProperties.fn.hideConfirmationDialog(); 
										});
										
						// AJAX time
						jQuery.ajax({
										type: "POST", 
										contentType: "application/json; charset=utf-8", 
										url: "JournalProperties.aspx/UpdateJournalPreferences", 
										data: '{JournalID: "' + intJournalID.toString() + '", PreferenceType: "journalstatus", PreferenceValue: "3"}', 
										dataType: "json", 
										success: function(objResult) {}, 
										error: function(objResult) {}
									});
					}
				}, 

			checkboxUpdate: 
				function() {
					// this method fires off AJAX calls for the various checkboxes on each journal "tile"
					var boolIsChecked			= jQuery(this).attr("checked");				// this will either be true or false, based on whether or not the checkbox is selected or not
					var objParentContainer		= jQuery(this).parents("li.checkbox");		// get the parent <li class="checkbox"> container for this checkbox
					var objTileContainer		= jQuery(this).parents("div.tile");			// let's try to find the <div class="tile"> container that houses all of these checkboxes -- we need the journal id stored within it
					
					if ((typeof(objParentContainer) == "object") && (typeof(objTileContainer) == "object")) {
						// looks like we were able to find our parent containers, so let's continue.
						// if we couldn't find it, we wouldn't be able to go any further as we'd be missing critical data required for the AJAX request

						// get the first <input type="hidden"> inside of our tile (<div class="tile">) parent container, which will give us the journal id
						var intJournalID			= parseInt(jQuery(objTileContainer).find("input[type=hidden]:first").val());
						
						if ((!isNaN(intJournalID)) && (intJournalID > 0)) {
							// journal id is numeric, and journal id is greater than 0
							var strPreferenceType		= jQuery(objParentContainer).attr("checkbox-type");		// get the checkbox-type="" attribute from the aforementioned <li> element
							var strPreferenceValue;																// placeholder variable for our value after we discern what it is
							
							switch (strPreferenceType.toLowerCase()) {
								case "journalstatus" : 
									strPreferenceValue			= ((boolIsChecked) ? "1" : "2");				// if the checkbox is checked, then set our preference value to "1", otherwise set it to "2" (inactive)
									break;
									
								default : 
									strPreferenceValue			= ((boolIsChecked) ? "1" : "0");				// if the checkbox is checked, then set our preference value to "1", otherwise set it to "0" (false/disabled)
									break;
							}
							
							// let's do the AJAX request
							// note the data: attribute in this call -- ASP requires that JSON-encoded data sent through an AJAX request is encapsulated as a string, otherwise it cannot unserialize it.
							// normally, the syntax would look like this:
							// [...], data: {JournalID: 123, PreferenceType: "abc"}, instead of '{JournalID: 123, PreferenceType: "abc"}'
							jQuery.ajax({
											type: "POST", 
											contentType: "application/json; charset=utf-8", 
											url: "JournalProperties.aspx/UpdateJournalPreferences", 
											data: '{JournalID: "' + intJournalID.toString() + '", PreferenceType: "' + strPreferenceType + '", PreferenceValue: "' + strPreferenceValue + '"}', 
											dataType: "json", 
											success: function(objResult) {}, 
											error: function(objResult) {}
										});
						}
					}
				}, 
				
			autosaveUpdate: 
				function() {
					// this method fires off the AJAX call to set the auto-save interval on the various journal "tiles"
					var objParentContainer		= jQuery(this).parents("div.tile").find("input[type=hidden]:first");		// find the <input type="hidden"> at the top of the tile (<div class="tile">) markup.
					
					if (typeof(objParentContainer) == "object") {
						var intJournalID			= parseInt(jQuery(objParentContainer).val());			// grab the journal ID from the hidden input we just targetted above.
						var intSaveInterval			= parseInt(jQuery(this).val());		// grab the value of the auto-save selectbox for this particular journal
					
						if ((!isNaN(intJournalID)) && (intJournalID > 0) && (!isNaN(intSaveInterval))) {
							// journal id and save interval are both numeric, so let's AJAX it up.
							jQuery.ajax({
											type: "POST", 
											contentType: "application/json; charset=utf-8", 
											url: "JournalProperties.aspx/UpdateJournalPreferences", 
											data: '{JournalID: "' + intJournalID.toString() + '", PreferenceType: "autosaveinterval", PreferenceValue: "' + intSaveInterval.toString() + '"}', 
											dataType: "json", 
											success: function(objResult) {}, 
											error: function(objResult) {}
										});
						}
					}
				}, 
				
			deleteDraft: 
				function(objContainer) {
					// this method handles removing a draft "tile" from the page, and upon removal, re-initializes the drafts scroll container for the given journal tile

					// grab the journal id from the <div class="tile"> container within this journal's <li> element.  we'll have to traverse up the tree quite a bit to get to the hidden input field, but it's doable.
					var intJournalID			= parseInt(jQuery(objContainer).parents(".drafts").siblings(".tile").find("input[type=hidden]:first").val());
					var intDraftID				= parseInt(jQuery(objContainer).siblings("input[type=hidden]:first").val());		// grab the first <input type="hidden"> at the same nesting level as the current link
					
					if ((!isNaN(intJournalID)) && (intJournalID > 0)) {
						var objParentContainer		= jQuery(objContainer).parent("li");				// target the <li> that houses all of the information for this particular draft tile
						
						jQuery(objParentContainer)
							.fadeOut(	function() { 
											// this function runs after the fadeout is complete
											var objDraftsList			= jQuery(this).parent("ol");		// traverse the tree upwards and find the first <ol> that contains all of the drafts
											
											if (typeof(objDraftsList) == "object") {
												// found it, so let's move on
												
												// obtain the id="" attribute from the <ol>, so we can grab the pointer to the scroll container API from our array that we populated during page load.
												var strDraftsElementID		= jQuery(objDraftsList).attr("id");
												
												if ((typeof(strDraftsElementID) == "string") && (strDraftsElementID.length)) {
													jQuery(this).remove(); 												// remove the <li> item we just faded out from the page

													// resize the container housing all of the draft tiles
													framework.journalProperties.fn.setDraftContainerSize(objDraftsList);
													
													var objDrafts				= jQuery(objDraftsList).find("li");		// get a list of all remaining <li> items inside the drafts <ol> container
													
													// update the drafts count in the bottom right corner of the journal tile
													jQuery(objDraftsList).parents(".drafts").siblings(".num-drafts").find("strong").find("span").html(objDrafts.length);
													
													if (objDrafts.length >= 4) {
														if (typeof(framework.journalProperties.prop.draftScrollContainers[strDraftsElementID]) == "object") {
															// reinitialize the jScrollPane scrollbar
															framework.journalProperties.prop.draftScrollContainers[strDraftsElementID].reinitialise();
														}
													} else {
														if (objDrafts.length == 0) {
															// hide the drafts container since there are no more drafts left
															jQuery(objDraftsList).parents(".drafts").removeClass("single-line").addClass("hidden");
														} else {
															// add single line class to the parent <div class=".drafts"> container since we're under 4 drafts now
															jQuery(objDraftsList).parents(".drafts").addClass("single-line");
														}
														
														if (typeof(framework.journalProperties.prop.draftScrollContainers[strDraftsElementID]) == "object") {
															// remove the scrollbar container since we don't need it anymore
															framework.journalProperties.prop.draftScrollContainers[strDraftsElementID].destroy();
														}
													}
													
													framework.journalProperties.fn.hideConfirmationDialog();
												}
											}
										});
										
						// AJAX time
						jQuery.ajax({
										type: "POST", 
										contentType: "application/json; charset=utf-8", 
										url: "JournalProperties.aspx/UpdateDraftStatus", 
										data: '{JournalID: "' + intJournalID.toString() + '", DraftID: "' + intDraftID.toString() + '", StatusType: "3"}', 
										dataType: "json", 
										success: function(objResult) {}, 
										error: function(objResult) {}
									});
					}
				}, 
			
			toggleDraftStatus:
				function() {
					// this method fires off the AJAX call for the specified draft to toggle it as active/inactive.
					
					// grab the journal id from the <div class="tile"> container within this journal's <li> element.  we'll have to traverse up the tree quite a bit to get to the hidden input field, but it's doable.
					var intJournalID			= parseInt(jQuery(this).parents(".drafts").siblings(".tile").find("input[type=hidden]:first").val());
					var intDraftID				= parseInt(jQuery(this).siblings("input[type=hidden]:first").val());		// grab the first <input type="hidden"> at the same nesting level as the current link
					
					if ((!isNaN(intJournalID)) && (intJournalID > 0) && (!isNaN(intDraftID)) && (intDraftID > 0)) {
						var boolIsActive;
						
						// does the draft "link" that was clicked have the "active" css class?  if it does, we remove it; if it doesn't, we add it.  (thus, it's a toggle)
						if (jQuery(this).hasClass("active")) {
							boolIsActive							= false;
							
							jQuery(this).removeClass("active");		// remove the active class, since we're going to be toggling the draft into inactive status
						} else {
							boolIsActive							= true;

							jQuery(this).addClass("active");		// add the active class, since we're going to the toggling the draft into active status
						}
						
						// AJAX time!
						jQuery.ajax({
										type: "POST", 
										contentType: "application/json; charset=utf-8", 
										url: "JournalProperties.aspx/UpdateDraftStatus", 
										data: '{JournalID: "' + intJournalID.toString() + '", DraftID: "' + intDraftID.toString() + '", StatusType: "' + ((boolIsActive) ? "1" : "2") + '"}', 
										dataType: "json", 
										success: function(objResult) {}, 
										error: function(objResult) {}
									});
					}
				}
		}
	}, 
	tooltips: {
		fn: {
			show:
				function() {
					var dblTooltipWidth;
					var dblTooltipX;
					var dblTooltipY;
					var dblPointerWidth;
					var dblPointerX;
					var dblParentWidth	= jQuery(this).parent().width();
					var dblParentMid	= (dblParentWidth / 2);
					var dblCurWidth		= jQuery(this).width();
					var dblCurHeight	= jQuery(this).height();
					var dblCurX			= jQuery(this).position().left + (dblCurWidth / 2);
					var dblCurY			= jQuery(this).position().top;
					var strTooltipText	= "";
					var objPrevTooltip	= jQuery("#standard-tooltip");
					
					// gather tooltip text
					if (jQuery(this).attr("title").length > 0) {
						strTooltipText		= jQuery(this).attr("title");
					} else {
						strTooltipText		= jQuery(this).text();
					}
					
					// remove existing tooltip
					if (objPrevTooltip.length) {
						jQuery(objPrevTooltip)
							.stop()
							.remove();
					}
					
					// create tooltip
					jQuery(this)
						.parent()
						.before("<div id=\"standard-tooltip\"><ins><del>&nbsp;</del></ins><strong>&nbsp;</strong></div>");
					
					// add text to tooltip
					jQuery("#standard-tooltip")
						.css("opacity", 0);
					jQuery("#standard-tooltip>strong")
						.html(strTooltipText);
					
					// grab measurements
					dblTooltipWidth		= jQuery("#standard-tooltip>strong").width() + (parseFloat(jQuery("#standard-tooltip>strong").css("paddingLeft").replace("px", "")) + parseFloat(jQuery("#standard-tooltip>strong").css("paddingRight").replace("px", ""))) - (parseFloat(jQuery("#standard-tooltip>strong").css("border-right-width").replace("px", "")) + parseFloat(jQuery("#standard-tooltip>strong").css("border-left-width").replace("px", "")));
					dblPointerWidth		= jQuery("#standard-tooltip>ins>del").width();
					dblTooltipY			= (dblCurY + (dblCurHeight / 2));
					
					if (dblCurX > dblParentMid) {
						// centerpoint of element is further right than left
						if ((dblCurX + (dblTooltipWidth / 2)) >= dblParentWidth) {
							dblTooltipX			= (dblCurX - dblTooltipWidth);
							dblPointerX			= dblTooltipWidth - dblPointerWidth;
							
							// set border radius so the top right corner isn't rounded, so the little pointer looks flush with the top right corner of the tooltip
							jQuery("#standard-tooltip").addClass("topright");
						} else {
							// we can center it
							dblTooltipX			= (dblCurX - ((dblTooltipWidth + dblCurWidth) / 2));
							dblPointerX			= ((dblTooltipWidth / 2) - dblPointerWidth);
						}
					} else if (dblCurX < dblParentMid) {
						// centerpoint of element is further left than right
						if ((dblCurX - (dblTooltipWidth / 2)) < 0) {
							dblTooltipX			= dblCurX;
							dblPointerX			= dblCurX;
							
							// set border radius so the top left corner isn't rounded, so the little pointer looks flush with the top left corner of the tooltip
							jQuery("#standard-tooltip").addClass("topleft");
						} else {
							// we can center it
							dblTooltipX			= (dblCurX - ((dblTooltipWidth + dblCurWidth) / 2));
							dblPointerX			= (dblTooltipWidth / 2) - (dblPointerWidth);
						}
					} else {
						// center it, since we appear to be dead center in the parent container
						dblTooltipX			= (dblCurX - ((dblTooltipWidth + dblCurWidth) / 2));
						dblPointerX			= (dblTooltipWidth / 2) - (dblPointerWidth);
					}
					
					// show tooltip
					jQuery("#standard-tooltip")
						.css(
								{
									"opacity": 1, 
									"left": dblTooltipX + "px", 
									"top": dblTooltipY + "px"
								}
							);
					jQuery("#standard-tooltip>ins")
						.css(
								{
									"left": dblPointerX + "px"
								}
							);
				}, 
				
			hide:
				function() {
					jQuery("#standard-tooltip")
						.stop()
						.animate(
									{
										"opacity": 0
									}, 
									250, 
									"linear");
				}
		}
	}
};
