// YEAH THIS IS SHITTY CODE.  DEAL WITH IT!
// contact: tom [at] windybits [dot] com

// CONSTANTS
var LOADING_ICON_ID = "loadingIcon";
var CONTENT_ID = "tmrContent";
var DROP_DOWN_ID = "dropdownWrap";
var TMR_INPUT_LINK_ID = "tmrInputUrl";
var SHOW_SOURCE_URL_ID = "source";
var TMR_INPUT_LINK_HTMLIFY_BUTTON_ID = "htmlify";
var TMR_RECENT_REPORTS_JSON_URL = "/yahoopipes/pipes/pipe.run?_id=a19688b52b6d09685a5a52b98d9373d1&_render=json";
var TMRONLINE_REGEX = /^http:\/\/(www\.)?tmronline\.com/;
var FETCH_ERROR_MESSAGE = "<p style='color: red;'>Failed to fetch URL!</p>";
var PARSE_ERROR_MESSAGE = "<p style='color: red;'>Remote content was not in expected format.  Unable to parse.</p><p style='color: red;'>This can happen with special newsletters or with very old newsletters (pre-2001 or so).</p>"
var TMRURL_QS_PARAM = "tmrUrl";

var DEFAULT_DROPDOWN_OPTION = "<option value=''>--Choose--</option>";
var SELECT_OPENING_TAG = "<select onchange='reloadSelf(this.options[this.selectedIndex].value)'>";
var SELECT_CLOSING_TAG = "</select>";

var RETURN_TO_TOP = "<p class='returnToTop'><a href='#top'>Return to top</a></p>";

var TMR_REMIX_TITLE = "<h1 id='top'>The May Report (remixed)</h1>";
var TOC_HEADING = "<h2>Table of Contents</h2>";
var ARTICLES_HEADING = "<h2>Articles</h2>"; 
var FOOTER = "";


var reloadSelf = function(tmrUrl) {
	if (tmrUrl == "") {
		// default option; do nothing
	} else {
		var encodedTmrUrl = encodeURI(tmrUrl);
		var newLocationUrl = window.location.protocol + "//" + window.location.hostname + window.location.pathname + "?" + TMRURL_QS_PARAM + "=" + encodedTmrUrl;
		window.location.href = newLocationUrl;
	} 
}

var fetchInputLink = function() {

	var inputUrl = $(TMR_INPUT_LINK_ID).value;
	reloadSelf(inputUrl);

}

var getRecentTmr = function() {

	var recentTmrUrl = "";

	var tmrAjaxReq = new Ajax(TMR_RECENT_REPORTS_JSON_URL, {
		method: "get"
	});

	tmrAjaxReq.addEvent('onComplete', function(respTxt) {
		var tmrRssObj = Json.evaluate(respTxt);
		createDropdown(tmrRssObj);
		// hide the spinner gif
		hideLoadingIcon();		
	});
	
	tmrAjaxReq.addEvent('onRequest', function() {
		// show the spinner gif
		showLoadingIcon();
	});

	tmrAjaxReq.addEvent('onFailure', function() {
		// hide the spinner gif
		hideLoadingIcon();	
		// display error message
		renderContent(FETCH_ERROR_MESSAGE);
	});	
	
	tmrAjaxReq.request();

}

var createDropdown = function(tmrRssObj) {

	var tmrCollection = tmrRssObj.value.items;
	
	dropdownHtml = SELECT_OPENING_TAG;
	dropdownHtml += DEFAULT_DROPDOWN_OPTION;
	for (var i=0; i < tmrCollection.length; i++) {
		var linkTitle = tmrCollection[i].title;
		var absoluteUrl = tmrCollection[i].link;
		dropdownHtml += "<option value='" + absoluteUrl + "'>" + linkTitle + "</option>";	
	}
	dropdownHtml += SELECT_CLOSING_TAG;
	
	document.getElementById(DROP_DOWN_ID).innerHTML = dropdownHtml;
	
}

var getRootRelativeTmrLink = function(absoluteUrl) {
	var relativeUrl = "/tmr" + absoluteUrl.replace(TMRONLINE_REGEX, "");
	return relativeUrl;
}

var fetchTmr = function(tmrUrl, tmrTitle) {

	// create relative URL from www.tmronline.com link, with local /tmr prefix
	var relativeUrl = getRootRelativeTmrLink(tmrUrl);

	var tmrAjaxReq = new Ajax(relativeUrl, {
		method: "get"
	});
	
	tmrAjaxReq.addEvent('onComplete', function(respTxt, reqObj) {
		var tmrHtml = getTmrHtml(respTxt);
		if (tmrHtml) {
			renderContent(tmrHtml);
			showSourceUrl(tmrUrl);
		} else {
			renderContent(PARSE_ERROR_MESSAGE);
			showSourceUrlFromError(tmrUrl);			
		}
		// hide the spinner gif
		hideLoadingIcon();
	});
	
	tmrAjaxReq.addEvent('onRequest', function() {
		// show the spinner gif
		showLoadingIcon();
	});	
	
	tmrAjaxReq.addEvent('onFailure', function() {
		// hide the spinner gif
		hideLoadingIcon();	
		// display error message
		renderContent(FETCH_ERROR_MESSAGE);
	});		
	
	// show the spinner gif and make the request
	tmrAjaxReq.request();
	
}

// Display a message about the original source of the content
var showSourceUrl = function(absoluteUrl) {
	var sourceMsg =  "The content below was originally published by <a href=\"http://themayreport.com\">Ron May</a>.  It is reformatted below; the original is <a href='" + absoluteUrl + "'>here</a>.";
	$(SHOW_SOURCE_URL_ID).innerHTML = sourceMsg;
}

// Display a message about the original source of the content
var showSourceUrlFromError = function(absoluteUrl) {
	var sourceMsg =  "ERROR! You'll need to <a href=\"" + absoluteUrl + "'>view</a> this particular report on Ron's site.";
	$(SHOW_SOURCE_URL_ID).innerHTML = sourceMsg;
}

// Show the spinner GIF
var showLoadingIcon = function() {
	document.body.style.backgroundColor = "#ccc";
	$(LOADING_ICON_ID).setStyle('display', 'block');
}

// Hide the spinner GIF
var hideLoadingIcon = function() {
	document.body.style.backgroundColor = "#F1E8C7";
	$(LOADING_ICON_ID).setStyle('display', 'none');
}

// Get the title from the newsletter
var getTmrTitle = function(contentBody) {
	var title = "";
	var htmlTagSplitTxt = "<";	
	var titleRegex = /The May Report:\s+\d{1,2}\/\d{1,2}\/\d{2,4}:?/i;
	var titleSplit = contentBody.split(titleRegex);
	
	if (titleSplit.length > 1) {
		var titleWithExtra = titleSplit[1];
		// split at the next html tag
		var titleWithExtraSplit = titleWithExtra.split(htmlTagSplitTxt);
		var scrubbedTitle = titleWithExtraSplit[0];
		title = "<h2>" + scrubbedTitle + "</h2>";
	} else {
		title = false;
	}
	return title;
}

// Get the html for the title
var getTitleHtml = function(title) {
	var titleHtml = "<h2>" + title + "</h2>";
	return titleHtml;
}

// Get the report's date
var getTmrDate = function(contentBody) {
	var dateTxt = "";
	var dateSplitTxt = "<td width=\"462\"><b>";
	var htmlTagSplitTxt = "<";
	var dateTxtWithExtra = contentBody.split(dateSplitTxt);
	if (dateTxtWithExtra.length > 1) {
		var dateTxtHtmlTagSplit = dateTxtWithExtra[1].split(htmlTagSplitTxt, 1);
		dateTxt = dateTxtHtmlTagSplit[0];
	}
	return dateTxt;
}

var getTmrDateHtml = function(dateTxt) {
	var dateHtml = "<h2 class='tmrDate'>Date of newsletter: " + dateTxt + "</h2>";
	return dateHtml;
}

// Get the text of the TOC from the newsletter
var getTocTxt = function(contentBody) {
	var tocSplitTxt = "TABLE OF CONTENTS";
	var tocWithExtra = "";
	// initially false
	var foundToc = false;
	var scoopSplitRegex = /Scoop section:?/i;
	var tocSplit = contentBody.split(tocSplitTxt);
	if (tocSplit.length == 1) {
		// we didn't find the table of contents
		// let's try the scoop
		var scoopSplit = contentBody.split(scoopSplitRegex);
		if (scoopSplit.length > 1) {
			tocWithExtra = scoopSplit[1];
			foundToc = true;
		}
	} else {
		tocWithExtra = tocSplit[1];
		foundToc = true;
	}
	
	if (foundToc) {
		var tocWithExtraSplit = tocWithExtra.split(/(_{5,100}|\+{5,100})\s*<br>/);
	
		// the actual table of contents
		var actualToc = tocWithExtraSplit[0];
	} else {
		// nothing to return :(
		var actualToc = false;
	}
	return actualToc;
}

// Get an array of TOC items
var getTocItemsArr = function(tocTxt) {
	// place the TOC items into an array
	var tocLines = tocTxt.split("<br>");
	
	// the scrubbed array
	var tocItems = [];
	
	for (var i=1; i < tocLines.length; i++) {
		// remove extraneous stuff from the line
		var scrubbedLine = tocLines[i].replace(/^\s+|\s+$/g,"");
		var checkValidLineInd = checkValidLine(scrubbedLine);
		if (checkValidLineInd) {
			scrubbedLine = scrubbedLine.replace(/^-{1,3}|_{3,100}/,"");
			scrubbedLine = scrubbedLine.replace(/^\s+|\s+$/g,"");
			if (scrubbedLine == "") {
				// do nothing.  not a meaningful line
			} else {
				tocItems.push(scrubbedLine);
			}
		}
	}
	
	// return the array of TOC items
	return tocItems;
}

// Return whether a line is a valid TOC entry
var checkValidLine = function(lineTxt) {
	
	var ind = false;

	if (lineTxt && lineTxt != "") {

		var validLineRegex = /^(\-\-|\d\D?\.|(The )?Scoop)/i;
		
		// return true/false depending on the match
		if (validLineRegex.test(lineTxt)) {
			ind = true;
		}
	
	}
	
	return ind;
		
}

// Get the HTML for the TOC
var getTocHtml = function(tocItemsArr) {
	// initialize
	var tocHtml = "<ul id=\"tmrToc\">";

	// walk through the array of TOC items, creating HTML
	for (var i=0; i < tocItemsArr.length; i++) {	
 		tocHtml += "<li class=\"tocItem\" id=\"tocItem_idx" + i + "\"><a href=\"#article_idx" + i + "\">" + tocItemsArr[i] + "</a></li>";	
	}

	// close the list
	tocHtml += "</ul>";
	
	// return the html
	return tocHtml;
}

// Get the array of TMR articles
var getArticlesArr = function(contentBody, tocItems) {

	// array of articles (without pretty formatting)
	var articlesArr = []

	// split the content body according to the TOC items
	for (var j=0; j < tocItems.length; j++) {
		// split the content body according to each TOC item
		var contentSplit = contentBody.split(tocItems[j]);
		
		// assemble the article body, plus extra stuff afterward
		// it's possible for the phrase we're splitting on to occur more than twice, so we need to 
		// concatenate everything after 2
		
		// initialize to empty string
		var articleBodyWithExtra = "";
		
		for (var csIdx = 2; csIdx < contentSplit.length; csIdx++) {
			articleBodyWithExtra += contentSplit[csIdx];
		}
		
		// initialize to empty string
		var article = "";
		
		if (j+1 == tocItems.length) {
			// last article
			// remove the "END OF REPORT" junk
			var articleSplit = articleBodyWithExtra.split("END OF REPORT");
			article = articleSplit[0];
		} else {
			// not the last article
			// split it at the point at which the next tocItem starts
			var articleSplit = articleBodyWithExtra.split(tocItems[j+1]);
			article = articleSplit[0];
		}
		
		// trim whitespace and extra crap.  yeah, i run it twice.  whatever.
		// article = article.replace(/^\s+|\s+$/g,"");
		article = article.replace(/^\s*(<br>)+|(<br>)+\s+$/g,"");
		article = article.replace(/^\s*(<br>)+|(<br>)+\s+$/g,"");
		
		// remove extraneous breaks and _____ fake-HRs
		// baaaad performance with this regex?
		//article = article.replace(/^(\s*<br\s?\/?>\s*)*|(\s*<br\s?\/?>\s*)*(_{5,100})*(\s*<br\s?\/?>\s*)*$/g,"");
		
		// add the article to the scrubbed array
		articlesArr.push(article);
		
	}
	
	// return the array of articles
	return(articlesArr);

}

// Get the HTML of all articles
var getArticlesHtml = function(articlesArr, tocItemsArr) {

	// initialize
	var fullArticlesHtml = "<div id=\"tmrArticles\">";

	for (var i=0; i < articlesArr.length; i++) {
		
		var articleHtml = "<h3 class=\"article-heading\" id=\"article_idx" + i + "\">" + tocItemsArr[i] + "</h3>";
		articleHtml += "<div class=\"article\">" + articlesArr[i] + "</div>";
		articleHtml += RETURN_TO_TOP;
		
		// add to constructed string
		fullArticlesHtml += articleHtml;	
	}

	// close the div
	fullArticlesHtml += "</div>";
	
	// return the html
	return fullArticlesHtml;
	
}

var getTmrHtml = function(contentBody) {
	
	// get the title
	// TO-DO: FIX THIS
	var title = getTmrTitle(contentBody);
	
	// get the title html
	if (title) {
		var titleHtml = getTitleHtml(title);
	} else {
		var titleHtml = "";
	}
	
	var tmrDate = getTmrDate(contentBody);
	var tmrDateHtml = getTmrDateHtml(tmrDate);
	
	// parse out the table of contents from the source html
	var tocTxt = getTocTxt(contentBody);
	
	// get a scrubbed array of TOC items
	if (tocTxt) {
		var tocItemsArr = getTocItemsArr(tocTxt);
	
		// build the html for the TOC
		var tocHtml = getTocHtml(tocItemsArr);
		
		// get a scrubbed array of articles
		var articlesArr = getArticlesArr(contentBody, tocItemsArr);
		
		// build the html of the articles
		var articlesHtml = getArticlesHtml(articlesArr, tocItemsArr);
		
		// construct the HTML-ified end product
		var tmrHtml = TMR_REMIX_TITLE + titleHtml + tmrDateHtml + TOC_HEADING + tocHtml + ARTICLES_HEADING + articlesHtml + FOOTER;
		
		return tmrHtml;
	} else {
		// nothing to return :(
		return false;
	}
	
}

var renderContent = function(html) {
	// only insert in the content div if it exists
	// this prevents a js error if the div is not present
	if ($(CONTENT_ID)) {
		$(CONTENT_ID).setHTML(html);
	}
}

var debugLog = function(txt) {
	// log only if "debug" attribute is supplied in query string of URL
	if (getQsVal("debug") == "true") {
		if (typeof console !== "undefined") {
			console.log(txt);
		} else {
			// non-FF
			alert(txt);
		}
	}
} 
 
var getQsVal = function(kyNm, QSTxt) {
	var kyVal = '';
	var argNmIdx = 0;
	var argValIdx = 1;
	if (QSTxt) {
		// do nothing
	} else {
		QSTxt = "";
	}
	if (QSTxt.length == 0) {
		QSTxt = location.search.substring(1);
	}
	var pairs = QSTxt.split('&');
	for(var pairsIdx = 0; pairsIdx < pairs.length; pairsIdx++) {
		var pair = pairs[pairsIdx].split('=');
		if (pair[argNmIdx].toLowerCase() == kyNm.toLowerCase()) {
			if (pair[argValIdx]) {
				kyVal = unescape(pair[argValIdx]);
			}
		}
	}
	return kyVal
} 


 
// add events
window.addEvent('domready', function() {

	// Get recent May Reports and populate them in a dropdown
	getRecentTmr();
	
	// Get the url parameter from the query string; if present, try to load it
	var tmrUrl = decodeURI(getQsVal(TMRURL_QS_PARAM));
	if (tmrUrl != "") {
		fetchTmr(tmrUrl);
	}

	$(TMR_INPUT_LINK_HTMLIFY_BUTTON_ID).addEvent('click', function() {
		fetchInputLink();
	});
	
});