/**
 * TaLE Feedback Database JavaScript Library.
 *
 * Requires: 
 * 		- jQuery 1.2.6
 * 		- det-utils-1.0.1
 */

/**
 * TFDI package
 */
namespace("DET.tale.tfdi");

/**
 * 
 */
DET.tale.tfdi.BrowserDetailPopup = function(containerId)
{
	var self = this;

	this.containerId = containerId;
	this.divs = new Array();
	this.divs["Home"] = "d_accessFromHomeDiv";
	this.divs["School"] = "d_accessFromSchoolTAFEDiv";
	this.divs["TAFE"] = "d_accessFromSchoolTAFEDiv";
	this.divs["Other"] = "d_accessFromOtherDiv";
	
	this.cancel = function()
	{
		jQuery("#detailDiv").hide();
		
		// Show all the select controls.
		jQuery("select").each(
				function()
				{
					this.style.display = "inline";
				});
	};
	
	this.changeAccessLocation = function()
	{
		var value = jQuery("#d_accessLocation").val();
		jQuery("#d_accessFromHomeDiv").hide();
		jQuery("#d_accessFromSchoolTAFEDiv").hide();
		jQuery("#d_accessFromOtherDiv").hide();
		jQuery("#" + self.divs[value]).show();
	};

	this.initialise = function()
	{
		var innerHTML = "<h1>Please Provide System Details</h1>" +
				"<table border='0' cellpadding='2' cellspacing='0' class='top'>" +
				"<tr>" +
				"<th><label for=\"d_os\">Operating System</label>:</th>" +
				"<td><input id=\"d_os\" name=\"d_os\" type=\"text\"/></td>" +
				"</tr>" +
				"<tr>" +
				"<th><label for=\"d_os_v\">Operating System Version</label>:</th>" +
				"<td><input id=\"d_os_v\" name=\"d_os_v\" type=\"text\"/></td>" +
				"</tr>" +
				"<tr>" +
				"<th><label for=\"d_browser\">Browser</label>:</th>" +
				"<td><input id=\"d_browser\" name=\"d_browser\" type=\"text\"/></td>" +
				"</tr>" +
				"<tr>" +
				"<th><label for=\"d_browser_v\">Browser Version</label>:</th>" +
				"<td><input id=\"d_browser_v\" name=\"d_browser_v\" type=\"text\"/></td>" +
				"</tr>" +
				"<tr><td colspan=\"2\">&nbsp;</td></tr>" +
				"<tr>" +
				"<th>" +
				"<label for=\"d_accessLocation\">Where do you access TaLe from?</label>" +
				"</th>" +
				"<td>" +
				"<select id=\"d_accessLocation\" name=\"d_accessLocation\">" +
				"</select>" +
				"</td>" +
				"</tr>" +
				"</table>" +
				"<div id=\"d_accessFromHomeDiv\">" +
				"<table cellpadding='2' cellspacing='0'>" +
				"<tr>" +
				"<th><label for=\"d_accessFromConnection\">Internet Connection</label>:</th>" +
				"<td>" +
				"<select id=\"d_accessFromConnection\" name=\"d_accessFromConnection\">" +
				"<option value=\"Not Selected\">Please select...</option>" +
				"<option value=\"ADSL\">ADSL</option>" +
				"<option value=\"Cable\">Cable</option>" +
				"<option value=\"Dialup\">Dialup</option>" +
				"<option value=\"Other\">Other</option>" +
				"</select>" +
				"</td>" +
				"</tr>" +
				"</table>" +
				"</div>" +
				"<div id=\"d_accessFromSchoolTAFEDiv\">" +
				"<table cellpadding='2' cellspacing='0'>" +
				"<tr>" +
				"<th><label for=\"d_accessFromSchoolCampus\">School/Campus Name</label>:</th>" +
				"<td>" +
				"<input id=\"d_accessFromSchoolCampus\" name=\"d_accessFromSchoolCampus\" type=\"text\"/>" +
				"</td>" +
				"</tr>" +
				"</table>" +
				"</div>" +
				"<div id=\"d_accessFromOtherDiv\">" +
				"<table cellpadding='2' cellspacing='0'>" +
				"<tr>" +
				"<th>" +
				"<label for=\"d_accessFromOther\">Other Details</label>:" +
				"</th>" +
				"<td><input id=\"d_accessFromOther\" name=\"d_accessFromOther\" type=\"text\"/></td>" +
				"</tr>" +
				"</table>" +
				"</div>" +
				"<div id=\"buttons\">" +
				"<input id=\"d_save\" type=\"button\" value=\"Save\"/>" +
				"<input id=\"d_cancel\" type=\"button\" value=\"Cancel\"/>" +
				"</div>";
		var popup = document.createElement("div");
		popup.id = "detailDiv";
		popup.innerHTML = innerHTML;
		
		document.getElementById(self.containerId).appendChild(popup);
		
		// Assign events
		jQuery("#d_save").bind("click", self.save);
		jQuery("#d_cancel").bind("click", self.cancel);
		jQuery("#d_accessLocation").bind("change", self.changeAccessLocation);
		
		// Assign values.
		if (jQuery("#detailsEntered").val() != "1")
		{
			try
			{
				var browser = new DET.tale.util.BrowserDetails();
				var os = browser.operatingSystem.split(" ");
				jQuery("#d_os").val(os[0]);
				jQuery("#d_os_v").val(os[1]);
				jQuery("#d_browser").val(browser.browser);
				jQuery("#d_browser_v").val(browser.browserVersion);
			}
			catch (e)
			{
				alert("Error retrieving browser information");
			}
		}
		
		try
		{
			DET.tale.tfdi.getOptions("d_accessLocation", jQuery("#d_accessLocation").val(), 
					function ()
					{
						self.changeAccessLocation();
					});
		}
		catch (e) 
		{
			// Swallow this error.
		}
		return this;
	};
	
	this.save = function()
	{
		var accessLocation = jQuery("#d_accessLocation").val();
		var accessDetail = "";
		if (accessLocation == "Home")
		{
			accessDetail = "Connection: " + jQuery("#d_accessFromConnection").val();
		}
		else if (accessLocation == "School" || accessLocation == "TAFE")
		{
			accessDetail = "School/Campus: " + jQuery("#d_accessFromSchoolCampus").val();
		}
		else
		{
			accessDetail = jQuery("#d_accessFromOther").val();
		}
		jQuery("#operatingSystem").val(jQuery("#d_os").val());
		jQuery("#osVersion").val(jQuery("#d_os_v").val());
		jQuery("#browser").val(jQuery("#d_browser").val());
		jQuery("#browserVersion").val(jQuery("#d_browser_v").val());
		jQuery("#accessLocation").val(accessLocation);
		jQuery("#accessDetail").val(accessDetail);
		jQuery("#detailsEntered").val(1);
		
		self.cancel();
	};
	
	this.show = function()
	{
		// Since this is a popup, hide all the select controls.
		jQuery("select").each(
				function()
				{
					if (this.id != "d_accessLocation" &&
							this.id != "d_accessFromConnection")
					{
						this.style.display = "none";
					}
				});
		
		var d = jQuery("#detailDiv").show();
		var ws = DET.tale.util.getWindowSize();
		var l = (ws.width / 2) - (d.attr("offsetWidth") / 2);
		var t = (ws.height / 2) - (d.attr("offsetHeight") / 2);
		d.css("left", l + "px");
		d.css("top", t + "px");
	};
};

/**
 * Report default constructor.
 * @param containerId - the ID of the container that the report will be rendered in.
 */
DET.tale.tfdi.Report = function(containerId)
{
	this.rows = new Array();
	this.cols = new Array();
	this.totals = new Array();
	this.displayCount = 0;
	this.displayStart = 0;
	this.containerId = containerId;
	//this.hasNameCol = false;
	
	/**
	 * Adds a column to the report.
	 * @param col - the String name of the column.
	 * @return void
	 */
	this.addColumn = function(column)
	{		
		this.cols.push(column);
	};
	
	/**
	 * Adds a row to the report.
	 * @param row - the DET.tale.tfdi.ReportRow object representing the row.
	 * @return void
	 */
	this.addRow = function(row)
	{
		this.rows.push(row);
	};
	
	this.addTotal = function(total)
	{
		this.totals.push(total);
	};
	
	/**
	 * Renders the report within a container.
	 * @return void
	 */
	this.render = function()
	{
		var self = this;
		
		// Check for the presence of Groups
		var hasGroups = false;
		for (var i = 0; i < self.cols.length; i++)
		{
			if (self.cols[i].className == "DET.tale.tfdi.ReportGroup")
			{
				hasGroups = true;
				break;
			}
		}
		
		var result = "<table cellpadding='2' cellspacing='2'>";
		if (hasGroups)
		{
			result += "<tr>";
			/*
			if (this.hasNameCol)
			{
				result += "<th></th>";
			}
			*/
			for (var i = 0; i < self.cols.length; i++)
			{
				if (self.cols[i].className == "DET.tale.tfdi.ReportGroup")
				{
					var group = self.cols[i];
					result += "<th colspan=\"" + group.columns.length + "\">" + group.label + "</th>";
				}
				else
				{
					result += "<th></th>";
				}
			}
			result += "</tr>";
		}
		result += "<tr>";
		/*
		if (this.hasNameCol)
		{
			result += "<th></th>";
		}
		*/
		for (var i = 0; i < self.cols.length; i++)
		{
			if (self.cols[i].className == "DET.tale.tfdi.ReportGroup")
			{
				var group = self.cols[i];
				for (var c = 0; c < group.columns.length; c++)
				{
					//result += "<th><a href='#' onclick='DET.tale.tfdi.doOrderBy(\"" + 
					//	this.cols[i].label + "\");'>" + this.cols[i].label + "</a></th>";
					result += "<th>" + group.columns[c].label + "</th>";
				}
			}
			else
			{
				result += "<th><a href='#' onclick='DET.tale.tfdi.doOrderBy(\"" + 
						this.cols[i].label + "\");'>" + this.cols[i].label + "</a></th>";
			}
		}
		result += "</tr>";
		
		var start = self.displayStart;
		var end = parseInt(self.displayStart) + parseInt(self.displayCount);
		
		for (var j = 0; j < self.rows.length; j++)
		{		
			var row = self.rows[j];
		
			if (this.displayCount == 0 || ((j + 1) > start && (j + 1) <= end))
			{
				result += "<tr class='" + ((j % 2 == 0) ? "a" : "b") + "'>";
				/*
				if (this.hasNameCol)
				{
					result += "<th>" + this.rows[j].name + "</th>";
				}
				*/
				for (var k = 0; k < self.cols.length; k++)
				{
					var col = self.cols[k];
				
					if (col.className == "DET.tale.tfdi.ReportGroup")
					{
						var group = col;
						for (var c = 0; c < group.columns.length; c++)
						{
							result += "<td>" + new String(row.getField(group.columns[c].id)) + "</td>";
						}
					}
					else
					{
						if (col.isHeader())
						{
							result += "<th>" + new String(row.getField(col.id)) + "</th>";
						}
						else
						{
							result += "<td>" + new String(row.getField(col.id)) + "</td>";
						}
					}
				}
				result += "</tr>";
			}
		}
		
		if (this.displayCount > 0 && this.displayCount < this.rows.length)
		{
			result += "<tr><td colspan='" + (this.cols.length + ((this.hasNameCol) ? 1 : 0)) + "'>";
			for (var l = 0; l < (this.rows.length / this.displayCount); l++)
			{
				var page = l + 1;
				if (this.displayStart != (l * this.displayCount))
				{
					result += "<a href='#' id='page" + page + "'>" + page + "</a> ";
				}
				else
				{
					result += page + " ";
				}
			}
			result += "</td></tr>";
		}
		result += "</table>";
		
		// Add totals
		result += "<table cellpadding='2' cellspacing='2'>";
		if (this.totals.length > 0)
		{
			result += "<tr><td colspan=\"" + ((this.hasNameCol) ? (this.cols.length + 1) : (this.cols.length)) + 
					"\">&nbsp;</td></tr>";			
			for (var m = 0; m < this.totals.length; m++)
			{
				result += "<tr class=\"a\"><th>" + this.totals[m].title + "</th><td colspan=\"" + 
						this.cols.length + "\"><strong>" + this.totals[m].value + "</strong></td></tr>";
			}
		}
		
		result += "</table>";	
					
		jQuery("#" + this.containerId).attr("innerHTML", result);
		
		// Assign page link clicks.
		if (this.displayCount > 0)
		{
			var noPages = (this.rows.length / this.displayCount);
			for (var m = 0; m < noPages; m++)
			{
				jQuery("#page" + (m + 1)).bind("click", 
						function() 
						{
							self.displayStart = (parseInt(this.innerHTML) - 1) * self.displayCount;
							self.render();
						});
			}
		}
	};
};

DET.tale.tfdi.ReportColumn = function(id, label, header)
{
	var self = this;
	self.className = "DET.tale.tfdi.ReportColumn";
	self.id = id;
	self.label = label;
	self.header = header;
	
	self.isHeader = function()
	{
		return self.header;
	};
	
	return self;
};

DET.tale.tfdi.ReportGroup = function(id, label)
{
	var self = new DET.tale.tfdi.ReportColumn(id, label);
	self.className = "DET.tale.tfdi.ReportGroup";
	self.columns = new Array();
	
	self.addColumn = function(column)
	{
		self.columns.push(column);
	};
	
	return self;
};

/**
 * ReportRow default constructor.
 */
DET.tale.tfdi.ReportRow = function()
{
	this.name = "";
	this.fields = new Array();

	/**
	 * Sets the name of the row (which will appear in the name column if it is enabled).
	 * @param name - a name/description for the row.
	 * @return void
	 */
	this.setName = function(name)
	{
		this.name = name;
	};
	
	/**
	 * Adds a field-value to the row. Makes sure any escaped tags are output correctly
	 * (otherwise breaks will be displayed as <br/> instead of a break).
	 * @param name - the name of the column that the value will be added to.
	 * @param value - the value to add to the column.
	 * @return void
	 */
	this.addField = function(name, value)
	{
		var val = value;
		val = val.replace(/&lt;/g, "<").replace(/&gt;/g, ">");
		this.fields[name] = val;
	};
	
	/**
	 * Retrieves a field-value from the row.
	 * @param name - the name of the column that the value will be retrieved from.
	 * @return The String field-value.
	 */
	this.getField = function(name)
	{
		return this.fields[name];
	};
};

/**
 * ReportTitle default constructor.
 */
DET.tale.tfdi.ReportTotal = function(title, value)
{
	this.title = title;
	this.value = value;
};

/**
 * JavaScript User table to allow easy UI sorting of users.
 * TODO Will need to be re-engineered to be more generic.
 * 
 * @param id - the id of the element which will hold the table.
 */
DET.tale.tfdi.Table = function(id)
{
	var self = this;
	self.id = id;
	self.data = new Array();
	self.$element = jQuery("#" + self.id);
	self.sB = "";
	
	self.addData = function(data)
	{
		self.data.push(data);
	};
	
	self.createHeader = function(name, property)
	{
		var $th = jQuery(document.createElement("th"));
		var $a = jQuery(document.createElement("a"));
		$a.attr("innerHTML", name);
		$a.attr("href", "#");
		$a.bind("click", function() { self.sortBy(property); });
		$th.append($a);
		
		return $th;
	};
	
	self.createData = function(value)
	{
		var $td = jQuery(document.createElement("td"));
		$td.attr("innerHTML", value);
		return $td;
	};
	
	self.render = function()
	{
		// Remove the table if it already exists.
		self.$element.find("table").remove();
	
		var $table = jQuery(document.createElement("table"));
		$table.attr("border", 1);
		$table.attr("cellpadding", 3);
		$table.attr("cellspacing", 2);
		$table.attr("width", "100%");
		
		var $trh = jQuery(document.createElement("tr"));
		$trh.append(this.createHeader("Name", "name"));
		$trh.append(this.createHeader("User Name", "userName"));
		$trh.append(this.createHeader("Association", "association"));
		$trh.append(this.createHeader("Date Assigned", "dateAssigned"));
		
		$table.append($trh);
	
		var output = "<table border='1' cellpadding='3' cellspacing='2' width='100%'>";
		output += "<tr><th>Name</th><th>User Name</th><th>Association</th><th>Date Assigned</th></tr>";
		for (var i = 0; i < self.data.length; i++)
		{
			var user = self.data[i];
			var $trd = jQuery(document.createElement("tr"));
			$trd.addClass((i % 2 == 0) ? "a" : "b");
			$trd.append(this.createData(user.name));
			$trd.append(this.createData(user.userName));
			$trd.append(this.createData(user.association));
			$trd.append(this.createData(user.dateAssigned));
			/*
			output += "<td><a href='mailto:" + user.email + "'>" + user.name + "</a></td>";
			output += "<td>" + user.userName + "</td>";
			output += "<td>" + user.association + "</td>";
			output += "<td>" + user.dateAssigned + "</td>";
			output += "</tr>";
			*/
			
			$table.append($trd);
		}      
		//self.$element.attr("innerHTML", output);
		self.$element.append($table);
	};
	
	self.sortBy = function(sortBy)
	{
		if (self.sB != sortBy)
		{
			self.sB = sortBy;
			self.data.sort(this.compareUsers);
		}
		else
		{
			self.data.reverse();
		}
		this.render();
	};
	
	self.compareUsers = function(a, b)
	{
		var result = 0;
		if (a[self.sB] < b[self.sB])
		{
			result = -1;
		}
		else if (b[self.sB] < a[self.sB])
		{
			result = 1;
		}
		else
		{
			result = 0;
		}
		return result;
	};
	
	return self;
};

DET.tale.tfdi.User = function(name, userName, email, association, dateAssigned)
{
	var self = this;
	
	self.name = name;
	self.email = email;
	self.userName = userName;
	self.association = association;
	self.dateAssigned = dateAssigned;
	
	return self;
};

/**
 * 
 */
DET.tale.tfdi.doOrderBy = function(column)
{
  var orderByDir = "ASC";
  if (jQuery("#orderBy").val() == column && 
      jQuery("#orderByDir").val() == "ASC")
  {
    orderByDir = "DESC";
  }
  else
  {
    jQuery("#orderBy").val(column);
  }
  jQuery("#orderByDir").val(orderByDir);
  DET.tale.tfdi.doSubmitReport();
};

/**
 * 
 */
DET.tale.tfdi.doSubmitReport = function(method)
{
	if (method)
	{
		jQuery("#method").attr("name", method);
	}
	jQuery("#refreshForm").trigger("submit");
};

/**
 * Validates the email address field in each issue entry screen.
 * 
 * @param jQ - jQuery object representing Email address field.
 * @return true if field is valid email address, false otherwise. 
 */
DET.tale.tfdi.doValidateIssueEmail = function(jQ)
{
  if (!DET.tale.validation.validateEmail(jQ.val()))
  {
    alert("Please enter a valid email address.");
    jQ.focus();
    return false;
  }
  return true;
}

/**
 * Checks that the search string contains some text before submitting the search.
 */
DET.tale.tfdi.doValidateQuickSearch = function()
{
  if (!DET.tale.validation.validateNotEmpty(jQuery('[name=searchString]').val()))
  {
    alert("Please enter some quick search text.");
    return false;
  }
  return true;
};

/**
 * Returns the default WYSIWYG (Yahoo) editor.
 * 
 * @param id - the id of the textarea to replace with the WYSIWYG editor.
 * @return The Yahoo Editor object.
 */
DET.tale.tfdi.getDefaultEditor = function(id)
{
	var result = new YAHOO.widget.Editor(id, { 
        height: "200px", 
        width: "600px", 
        dompath: false, 
        animate: true
        }); 
	return result;
};

/**
 * Loads a list of options from the Scarab database and populates
 * the corresponding select control with the results. 
 * 
 * @param fieldName the name of the field to retrieve options for.
 * @param value the selected field value (to be set after the options are retrieved).
 * @param callback a function that is called when the ajax call finishes.
 * @return void
 */
DET.tale.tfdi.getOptions = function(fieldName, value, callback)
{
	var fN = (fieldName.indexOf("_") == -1) ? fieldName : fieldName.substring(fieldName.indexOf("_") + 1);
	jQuery.getJSON("/tfdi/ajax/getOptions.jsp", { fieldName: fN },
			function(json)
			{
				var field = document.getElementById(fieldName);
				for (var i = 0; i < json.length; i++)
				{
					field.options[field.options.length] = 
							new Option(json[i].optionDisplay, json[i].optionValue);
				}
				if (value != null)
				{
					field.value = value;
				}
				if (callback != null)
				{
					callback();
				}
			});
};

/**
 * Retrieves the page URL and title and puts them into hidden input fields.
 * @return void
 */
DET.tale.tfdi.getPageInformation = function()
{
	jQuery("#pageUrl").val(escape(window.location));
	jQuery("#pageTitle").val(document.title);
};

/**
 * Opens the feedback details page in a new window. This window then populates
 * hidden inputs in the opener window.
 * @return void
 */
DET.tale.tfdi.openDetailWindow = function()
{
	window.open("/tfdi/feedbackDetail.html", "detailWindow", 
			"status=0, toolbar=0, location=0, menubar=0, height=400, width=600");
};

/**
 * 
 */
DET.tale.tfdi.displayLightBox = function(text, callback)
{
	hideForLightBox();
	new PBBAcpBox({ BoxStyles: { 'width': 494 }}).alert(
			text,
            {
            	onComplete: function() 
            	{ 
                    if (callback != null)
                    {
                    	callback();
                    }
                    showForLightBox();
                } 
            });
};