

Screener_class.prototype.initSections = function (section) {
	// Hold the data returned from getSectionMatches
	this.screenResults = {"saved":[], "recent":[], "canned":[]};
	// Hold the screens from the old Screener which contain invalid fields (populated in getSectionMatches)
	this.conversionScreenErrors = [];
	// Hold a count so we know when all sections are retrieved from getSectionMatches
	this.sectionsCalled = 0;
	this.doCount = true;
	
	// Either call one section or get them all
	if (section) {
		this.sectionLabel = section;
		this.section = section.toLowerCase().replace(/\s/,"");
		this.doCount = false;
		this.getSectionMatches(this.section);
	} else {
		for (var i=0; i<this.getSections().length; i++) {
			this.getSectionMatches(this.getSections()[i].url, this.getSections()[i]["label"]);
		}
	}
	
	var expandableContainerTitles = Element.parseSelector("h3.expandableContainerTitle a");

	for (var i=0; i<expandableContainerTitles.length; i++) {
		Events.add({element:expandableContainerTitles[i],type:"click",handler:this.expandableContainerClickEvent,context:this});
	}

	this.createCommonTopLinks();

	
};


Screener_class.prototype.getSections = function () {
	return [
		{"url":"stocks", "label":"Stocks"}
		,{"url":"options", "label":"Options"}
		,{"url":"mutualfunds", "label":"Mutual Funds"}
		,{"url":"etfs", "label":"ETFs"}
	];
};


Screener_class.prototype.getSectionMatches = function (section, label) {
	this.loadContentBuffer({
		 page:buildAbsolutePath("/screener/"+section+"/buffer_getMatches.asp")
		,data:{retrieveMatchesSaved:true, retrieveMatchesRecent:true, section:label, page:this.section||"overview"}
		,context:this
		,onload:this.saveScreenResults
	});
};


Screener_class.prototype.saveScreenResults = function () {
	for (var screenType in this.matches) {
		for (var i=0, len=this.matches[screenType].length; i<len; i++) {
			// Add the screener label to the object properties since it's not available in the results
			this.matches[screenType][i]["screener"] = this.screenerSectionLabel || this.sectionLabel;
		}
		// Concat the results
		this.screenResults[screenType] = this.screenResults[screenType].concat(this.matches[screenType]);
	}
	
	// Concat the conversion errors
	this.conversionScreenErrors = this.conversionScreenErrors.concat(this.conversionErrors);
	
	if (this.doCount) {
		// Update the count and check if we're done getting results
		this.sectionsCalled++;
		if (this.getSections().length == this.sectionsCalled) {
			this.GUI_displayMatches();
		}
	} else {
		this.GUI_displayMatches();
	}
};


Screener_class.prototype.GUI_displayMatches = function () {
	
	// Handle error messages for old saved screens with invalid fields
	this.handleInvalidScreens();
	
	if (Element.get("headersaved")) {

		// saved screens
		this.drawScreenTable("saved");
		
		// recent screens
		this.drawScreenTable("recent");
		
	}

	// canned screens
	this.drawCannedTable();
	
	// If we're on the Stocks or Mutual Funds overview pages,
	// select the first overview group for the canned screens
	if (this.sectionLabel) {
		myevent = Events.add({
			element:Element.parseSelector("#predefinedGroups a.groupLink", "cannedScreensContainer", "first")
			,type:"click"
			,handler:this.toggleCannedGroups
			,context:this
		});

		myevent.fire();
	}
};


Screener_class.prototype.drawScreenTable = function (screenType) {
	
	// Sort by most recent screen
	SortByField(this.screenResults[screenType],"timestamp", 0);
	
	// Draw the row data
	var len = this.screenResults[screenType].length;
	var bodyRows = [];
	var date, name, screener, criteria, matches;
	var classes = "";
	var url, deleteButton;
	
	var createScreen = Element.create("div");
	if (this.section) {
		Element.create("a", {"href":buildAbsolutePath("/screener/"+this.section+"/screener.asp?method=new")}, "Create a Screen", createScreen);
	} else {
		Element.create("span", {}, [
			"Create your own ",
			,Element.create("a", {"href":buildAbsolutePath("/screener/stocks/screener.asp?method=new")}, "Stock Screen")
			,", "
			,Element.create("a", {"href":buildAbsolutePath("/screener/mutualfunds/screener.asp?method=new")}, "Mutual Fund Screen")
			,", or "
			,Element.create("a", {"href":buildAbsolutePath("/screener/etfs/screener.asp?method=new")}, "ETF Screen")
		], createScreen);
	}
	Element.create("span", {}, "&nbsp;and save it for future visits.", createScreen);
	
	if ("saved" == screenType && 0 == len) {
		// No screens created yet
		bodyRows.push(Element.create("tr", {}, [
			Element.create("td", {"colspan":"5", "style":"border:0;padding:0"}, [
				Element.create("div",{id:"nosavedscreens",className:"tablemessage"},[
					Element.create("h3",{},"No Saved Screens"),
					createScreen
				])
			])
		]));
		Element.remove("savedThead");
	} else {
		for (var i=0; i<len; i++) {
			date = msToJsDate(parseFloat(this.screenResults[screenType][i]["timestamp"]));
			name = this.screenResults[screenType][i]["name"];
			screener = this.screenResults[screenType][i]["screener"];
			criteria = this.screenResults[screenType][i]["criteriaListSimple"];
			matches = this.screenResults[screenType][i]["matches"];

			if (i >= 5) {
				classes = "limit none";
			}

			// Construct the url for the links
			url = "../" + screener.toLowerCase().replace(/\s/, "") + "/results.asp?";
			if ("saved" == screenType) {
				url += "savedName=" + Common.encode(name);
			} else if ("recent" == screenType) {
				url += "recentNumber=" + i;
			}

			deleteButton = ("saved" == screenType) ? Element.create("a", {"href":"javascript:void(0)", "class":"remove", "title":"Delete " + name}, "&nbsp;") : "";
			Events.add({element:deleteButton, type:"click", handler:this.deleteScreen, context:this, data:screener});
			
			var nameLinkClass = ""
			if ("saved" == screenType) {nameLinkClass = "screenName";}
			// Create the table rows
			bodyRows.push(Element.create("tr", {"class":classes}, [
				Element.create("td", {}, [
					,Element.create("div", {className:"fleft"}, [
							deleteButton
							,Element.create("a", {"href":url,"class":nameLinkClass}, this.escapeInput(name))
					])//nameLinkClass
				//	,Element.create("div", {className:"fleft"} )
				//	,Element.create("div", {className:"clear"})
				]),
				Element.create("td", {}, screener.replace(/s$/,"")),
				Element.create("td", {}, criteria),
				Element.create("td", {"class":"alignRight"}, [(date.getMonth()+1), "/", date.getDate(), "/", date.getFullYear().toString().replace(/\d\d(\d\d)/,"$1")]),
				Element.create("td", {"class":"borderRightNone alignRight"}, [
					Element.create("a", {"href":url}, matches)
				])
			]));
		}
	}
	
	if (screenType == "saved" && i>5) {
		var viewalllink = Element.create("a", {"id":"viewAllSaved", "href":"javascript:void(0)", "class":"normal"}, "View All");
		var viewall = Element.create("span", {"class":"padLeft10"}, viewalllink);
		Element.addChild("headersaved", viewall);
	}
	
	var tbody = Element.create("tbody", {}, bodyRows);
	var oldTbody = Element.parseSelector("tbody", screenType+"Table", "first");
	Element.remove(oldTbody);
	Element.addChild(screenType+"Table", tbody);
	Events.add({element:viewalllink, type:"click", handler:this.toggleRows, context:this});
	
};


Screener_class.prototype.drawCannedTable = function () {
	var screenType = "canned";
	var screens = this.screenResults[screenType];
	var limit = screens.length;
	var bodyRows = [];
	var cell = 1;
	var tr, trClass, colspan, name, link, screener, screenerPath, nextCell, description, overviewGroup, featured, nextGroup;
	
	// On the Overview Page
	if (!this.sectionLabel) {
		// Discard all but the featured screens
		for (var i=0, featured=[]; i<limit; i++) {
			if (!screens[i]["featured"]) {
				screens.splice(i,1);
				i--;
				limit--;
			}
		}
		limit = screens.length;
		
		// Sort by screener
		SortByField(screens,"screener", 0);
		
		// Group the screens and sort by the featuredOrder property
		var screenNum = this.getSections().length;
		var rScreens = [];
		var rTemp = [];
		for (var i=0; i<screenNum; i++) {
			rTemp = screens.slice(i*4, i*4+4); // 4 is the number of featured screens per screener type
			SortByField(rTemp, "featuredOrder", 1);
			for (j=0; j<rTemp.length; j++) {
				rScreens.push(rTemp[j]);
			}
		}
		screens = rScreens;
	}
	
	// Output the screens
	for (var i=0; i<limit; i++) {
		
		// Ignore screens with display:false
		if (screens[i]["display"] && screens[i]["display"] == "false") {
			continue;
		}
		
		name = screens[i]["label"];
		link = screens[i]["name"];
		screener = screens[i]["screener"];
		screenerPath = screener.toLowerCase().replace(/\s/, "");
		nextCell = screens[i+1];
		description = screens[i]["description"];
		overviewGroup = screens[i]["overviewGroup"];
		nextGroup = (nextCell) ? nextCell["overviewGroup"] : null;
		
		// Create a new row if this is the first cell in the row
		if (1 == cell) {
			tr = Element.create("tr");
			if (this.sectionLabel) {
				if (0 == i) {
					this.overviewGroup = overviewGroup;
				} else if (this.overviewGroup != overviewGroup) {
					this.overviewGroup = overviewGroup;
					Element.addClass(tr, "none");
				}
				trClass = this.overviewGroup.replace(/\s/g,"") + "Screens";
				Element.addClass(tr, trClass);
			}
		}
		
		
		// Construct the url for the links
		url = "../" + screenerPath + "/results.asp?";
		url += "cannedName=" + Common.encode(link);
		
		var screenerLabel = (!this.sectionLabel) ? Element.create("span", {"class":"lighter"}, ["(", screener, ")"]) : "";
		
		// Draw the current cell
		Element.create("td", {}, [
			Element.create("a", {"href":url}, name),
			screenerLabel,
			Element.create("div", {"class":"description"}, description)
		], tr);
		
		if (1 == cell && nextCell && (!this.overviewGroup || this.overviewGroup == nextGroup)) {
			cell++;
		} else {
			bodyRows.push(tr);
			cell = 1;
		}
		
		// If the next cell isn't part of this group, or if we've reached the limit, draw the "More" link
		if (!this.sectionLabel && (undefined == nextCell || screener != nextCell["screener"])) {
			url = "../" + screenerPath + "/overview.asp";
			tr = Element.create("tr");
			Element.create("td", {"colspan":"2", "class":"padTop padBot"}, [
				Element.create("a", {"class":"normal", "href":url}, ["More", "&nbsp;", screener.replace(/s$/,""), " Screens..."])
			], tr);
			if (nextCell) {
				screener = nextCell["screener"];
			}
			cell = 1;
			bodyRows.push(tr);
		}
	}
	
	// If we're not on the overview page, draw the canned group links
	if (this.sectionLabel) {
		for (var i=0, groups=[]; i<screens.length; i++) {
			groups.push(screens[i]["overviewGroup"]);
		}
		groups = this.util.arrayRemoveDuplicates(groups);
		var groupLinks = [];
		for (var i=0; i<groups.length; i++) {
			var group = groups[i];
			group = group.substring(0,1).toUpperCase() + group.substring(1,group.length);
			groupLinks.push(Element.create("a", {"class":"groupLink" + ((0==i)?" selected":"")}, group));
			if (groups[i+1]) {
				groupLinks.push(Element.create("span", {"class":"pipe"}, "|"));
			}
		}
		Element.addChild("predefinedGroups", groupLinks);
		Events.add({element:Element.parseSelector("a.groupLink", "predefinedGroups"), type:"click", handler:this.toggleCannedGroups});
	}
	
	var tbody = Element.create("tbody", {}, bodyRows);
	var oldTbody = Element.parseSelector("tbody", screenType+"Table", "first");
	Element.remove(oldTbody);
	Element.addChild(screenType+"Table", tbody);
};


Screener_class.prototype.toggleRows = function (e, el, data) {
	Events.cancel(e);
	if (Element.parseSelector("tbody tr", "savedTable").length > 5) {
		Element.toggleClass(Element.parseSelector("tbody tr.limit", "savedTable"), "none");
		if ("View All" == Element.get("viewAllSaved").innerHTML) {
			Element.setHTML("viewAllSaved", "View Recent 5");
		} else {
			Element.setHTML("viewAllSaved", "View All");
		}
	}
	return false;
};


Screener_class.prototype.toggleCannedGroups = function (e, el, data) {
	Events.cancel(e);
	var theClass = el.innerHTML.replace(/\s/g,"") + "Screens";
	var selector = "tbody tr." + theClass;
	Element.removeClass(Element.parseSelector("a.selected", "predefinedGroups"), "selected");
	Element.addClass(el, "selected");
	Element.addClass(Element.parseSelector("tbody tr", "cannedTable"), "none");
	Element.removeClass(Element.parseSelector(selector, "cannedTable"), "none");
	return false;
};


Screener_class.prototype.setSticky = function (name,value,stickyType) {
	this.loadContentBuffer({
		 page:"../setSticky.asp"
		,data:{name:name,value:value,type:stickyType}
	});
};


Screener_class.prototype.handleInvalidScreens = function () {
	// if a user preference is not set for hiding the screen (returned from getSectionMatches),
	// draw the screen
	
	var errors = [];
	for (var i=0; i<this.conversionScreenErrors.length; i++) {
		for (var item in this.conversionScreenErrors[i]) {
			errors.push(this.conversionScreenErrors[i][item]);
		}
	}
	
	var numErrors = errors.length;
	if ("true" == this.showInvalidScreens && numErrors > 0) {
		var div = Element.create("div", {"id":"screenErrors"});
		var ul = Element.create("ul", {}, null, div);
		
		var url;
		for (var i=0; i<numErrors; i++) {
			url = "../" + errors[i][0]["url"] + "/screener.asp?savedName=" + Common.encode(errors[i][0]["name"]);
			Element.create("li", {}, [
				Element.create("span", {"class":"screenErrorName"}, errors[i][0]["name"])
				,": "
				,Element.create("span", {"class":"screenErrorReason"}, errors[i][0]["reason"])
				,Element.create("span", {"class":"screenErrorLink"}, [
					"("
					,Element.create("a", {"href":url}, "Modify screen")
					,")"
				])
			], ul);
		}
		
		var a = Element.create("a", {"id":"hideErrorMessages", "href":"javascript:void()"}, "Hide message");
		Element.create("p", {}, a, div);
		
		Element.addChild("errorMessageContainer", div);
		Element.removeClass("conversionError", "none");
		
		var name = "showInvalid" + (this.section||"overview") + "Screens";
		
		Events.add({
			element:a
			,type: "click"
			,handler:function(){
				this.setSticky(name, "false", "session");
				Element.remove("conversionError");
				return false;
			}
			,context:this
		});
	}
	
	return false;
	
};


Screener_class.prototype.expandableContainerClickEvent = function (e,el,data) {
	Events.cancel(e);
	el.blur();
	var expanded = Element.hasClass(el,"expanded");
	var sticky = Element.hasClass(el,"useSticky");

	var expandName = el.getAttribute("expandName");

	var expandableContainerContent = Element.parseSelector('div[expandName="'+expandName+'"]');
	
	Element.switchClass(el,"expanded",!expanded);
	Element.switchClass(expandableContainerContent,"none",expanded);

	if (sticky) {
		this.setSticky("ExpandableState_" + expandName,expanded?"collapsed":"expanded");
	}
};


Screener_class.prototype.deleteScreen = function (e, el, data) {
	Events.cancel(e);
	var parentTR = Element.getParent(el,"tr");
	var name = el.getAttribute("title").replace(/Delete /, "");
	data = data.replace(/\s/,"");
	var page = buildAbsolutePath("/screener/" + data + "/buffer_saveScreen.asp");
	if (confirm ("Delete the " + name + " screen?")) {
		this.loadContentBuffer({
			 page:page
			,data:{name:name, action:"delete"}
			,onload:function(){
					Element.remove(parentTR);
					var element = Element.parseSelector("table#savedTable tbody tr.none", "right", "first");
					Element.removeClass(element, "none");
					Element.removeClass(element, "limit");
					
					if (Element.parseSelector("table#savedTable tbody tr").length <= 5) {
						Element.remove("viewAllSaved");
						
						if (Element.parseSelector("table#savedTable tbody tr").length == 0) {
							Element.remove("savedThead");
						}
					}
				}
		});
	}
	return false;
};


// Utilitity Methods
Screener_class.prototype.util = {

	// arrayIndexOf( value, begin, strict ) - Return index of the first element that matches value
	arrayIndexOf:function(arr, v, b, s ) {
		for( var i = +b || 0, l = arr.length; i < l; i++ ) {
			if( arr[i]===v || s && arr[i]==v ) { return i; }
		}
		return -1;
	}
	,
	// arrayRemoveDuplicates(arr) - Remove duplicate values
	arrayRemoveDuplicates:function(arr, b ) {
		var a = [], i, l = arr.length;
		for( i=0; i<l; i++ ) {
			if( this.arrayIndexOf(a, arr[i], 0, b ) < 0 ) { a.push( arr[i] ); }
		}
		return a;
	}
};
