/* --------------------------- INTUIT CONFIDENTIAL ---------------------------

	spendingOvertime.js

	Written by		Date 
	Jason Harris	07/14/10
	
	Revised by		Date		Summary of changes
	Mickey Roberson	08/25/10	[S674] The SOT table is now composed of two separate
								adjoining tables.  The leftmost is fixed while
								the rightmost scrolls horizontally.
	Mickey Roberson	08/30/10	[DE1610] Integrated the deferred printing mechanics.
	Mickey Roberson 08/30/10	[DE1594] Added stored state for the disclosure acuators.
	Mickey Roberson	10/04/10	[DE1788] The clicked date is now passed back to Cocoa.
	Mickey Roberson	10/13/10	[DE1799] Now passes back if the clicked amount was an expense.
	Mickey Roberson	10/20/10	[DE1799] Correct parent cateogry/expense type is now passed back
	Mickey Roberson	10/29/10	[DE1889] Now indicates that the report filter time range should be used
									when clicking a category title on the left.
	Mickey Roberson	10/29/10	[DE1621] Indented categories/tags will now be truncated with ellipsis
 
	Copyright 2010 Intuit, Inc All rights reserved. Unauthorized
	reproduction is a violation of applicable law. This material contains
	certain confidential and proprietary information and trade secrets of
	Intuit, Inc.
		
	RESTRICTED RIGHTS LEGEND
		
	Use, duplication, or disclosure by the Government is subject to
	restrictions as set forth in subdivision (b) (3) (ii) of the Rights in
	Technical Data and Computer Software clause at 52.227-7013.
		
	Intuit, Inc
	P.O. Box 7850
	Mountain View, CA 94039-7850

----------------------------- INTUIT CONFIDENTIAL ------------------------- */

var gSpendingOverTimePrintToken = undefined;

function SpendingOverTimeInit()
{
	gSpendingOverTimePrintToken = CreateDeferredPrintingToken();
	FilterSettingsInit(true);
	InitRows();
	InitFixedRows();
}

function GraphHasDisplayed()
{
	if(undefined != gSpendingOverTimePrintToken)
		CheckInDeferredPrintingToken(gSpendingOverTimePrintToken);
}

function InitFixedRows() {
	
	var rows = $('.tableFixedData tbody tr');
	
	if(rows.length == 0 && undefined != gSpendingOverTimePrintToken)
	   CheckInDeferredPrintingToken(gSpendingOverTimePrintToken);
		
	
	rows.each(function() {
			  var element = $(this);

			  var level = parseInt(element.attr('level'));
			  var padding = 14 + level * 14;
			  var firstTD = element.find("td:first");
			  var style = firstTD.attr("style");
			  if (undefined !== style)
				style = style + " ";
			  else
				style = "";
			  style = style + "padding-left: " + padding + "px;";
			  firstTD.attr("style", style);
			  
			  // Need to reduce the width for padded cells to make the ellipsis
			  // work as expected.
			  if(padding > 14)
			  {
				  width = firstTD.css("width");
				  
				  if(width == undefined)
					width = 155; //Reasonable default value
			  
				  width = parseInt(width);
				  
				  // All of them are padded at least 14, so only adjust larger widths
				  width -= (padding-14);
				  firstTD.css("width", width + "px");
			  }
			  
			  if (_ChildRows(element, false).length) {
					element.addClass("collapsible");
					element.addClass("opened");

			  
					//Check if there is stored state for the rows
					if( window.viewController )
					{
						var stateID = _GenerateRowID(element);
						var actuatorState = window.viewController.TableState( stateID, actuatorState );

						if(actuatorState == "opened")
						{
							//Open the rows in this table
							_OpenRows(element, true, false, false);
			  
							//Open the rows in the right side table
							var valuesRow = $('#tableData tbody tr');
							valuesRow.each(function() {
										   var valueRow = $(this);
										   if(valueRow.attr('quickenID') == element.attr('quickenID')) {
												_OpenRows(valueRow, false, false, false);
										   }
										   });
						} else {
							//Close the rows in this table
							_CloseRows(element, true, true);
			  
							//Close the rows in the right side table
							var valuesRow = $('#tableData tbody tr');
							valuesRow.each(function() {
										   var valueRow = $(this);
										   if(valueRow.attr('quickenID') == element.attr('quickenID')) {
												_CloseRows(valueRow, true, false, false);
										   }
										   });
						}
					}

					element.find("td:first-child").prepend("<span class='actuator'></span>");
				  
					element.click(function(e) {
							var row =$(this);
								var table = $('#tableData tbody');
							var tableBody = $('tbody');
							var tableOffset = (table.offset().left-table.position().left+tableBody.offset().left - 30);
							var disclosurePadding = 14;
								  
							//If the disoclure actuator is being clicked expand the rows
							if(e.pageX >= tableOffset && e.pageX <= tableOffset+disclosurePadding) {
								var childrenIncluded = e.altKey;
								
								if (row.hasClass("closed")) {
									_OpenRows(row, true, childrenIncluded, true);
									var valuesRow = $('#tableData tbody tr');
									valuesRow.each(function() {
										var valueRow = $(this);
										if(valueRow.attr('quickenID') == row.attr('quickenID')) {
											_OpenRows(valueRow, true, childrenIncluded, false);
											throw $break;
										}
									});
								} else if (row.hasClass("opened")) {
									_CloseRows(row, true, childrenIncluded, true);
									var valuesRow = $('#tableData tbody tr');
									valuesRow.each(function() {
										var valueRow = $(this);
										if(valueRow.attr('quickenID') == row.attr('quickenID')) {
											_CloseRows(valueRow, true, childrenIncluded, false);
											throw $break;
										}
									});
								
								}
							} else { //Otherwise open the selected row or it's parent category in category explorer
								var qID = row.attr("quickenID");
								if(qID.substring(qID.length-1,qID.length) == "u")
								{
								  var parentCategoryRow = FindParentCategoryRowForChild(this);
								  CategoryRowClicked(parentCategoryRow.attr("quickenID"), "Total", true);
								} else {
									CategoryRowClicked(row.attr("quickenID"), "Total", true);
								}
							}
							
							return false;
							});
			  } else {
					element.click(function(e) {
								  var row = $(this);
								  var qID = row.attr("quickenID");
								  
								  if(IsATagID(qID))
								  {
									  var parentCategoryRow = FindParentCategoryRowForChild(this);
									  CategoryRowClicked(parentCategoryRow.attr("quickenID"), "Total", true);
								  } else {
									  CategoryRowClicked(row.attr("quickenID"), "Total", true);
								  }
					});
			  }
			  
		  });
}

function ColumnHeaderValueForIndex(colIndex)
{
	var headerCols = $('#tableData thead td');
	return headerCols[colIndex].textContent;
}


function InitRows() {
	var rows = $('#tableData tbody tr');

	rows.each(function() {
		var element = $(this);
			  
		if (_ChildRows(element, false).length) {
			element.addClass("collapsible");
			element.addClass("opened");
		}			
		
		element.click(function(e) {
					  var colIndex = $(this).children().index(e.target);
					  var colDate = ColumnHeaderValueForIndex(colIndex);
					  var row = $(this);
					  var qID = row.attr("quickenID");
					  var isExpense = ($(e.target).hasClass("negative") || $(e.target).hasClass("zero"));

					  if(IsATagID(qID))
					  {
						var parentCategoryRow = FindParentCategoryRowForChild(this);
						var parentElement = $(parentCategoryRow.children()[colIndex]);
					  
						// Since the parent category will be displayed, check the parent for isExpense
						isExpense = parentElement.hasClass("negative") || parentElement.hasClass("zero");
						CategoryRowClicked(parentCategoryRow.attr("quickenID"), colDate, isExpense);
					  } else {
						  CategoryRowClicked(row.attr("quickenID"), colDate, isExpense);
					  }
		});
		
	});
}

function IsUncategorizedID(quickenID)
{
    if (window.viewController)
        return (quickenID == window.viewController.CategoryInternalNameForUncategorized());

    return false;
}

function IsACategoryID(quickenID)
{
	return (quickenID.substring(quickenID.length-1, quickenID.length) == "c");
}

function IsATagID(quickenID)
{
	return (quickenID.substring(quickenID.length-1, quickenID.length) == "u");
}

function FindParentCategoryRowForChild(childRowObject)
{
	var rows = $('#tableData tbody tr');
	var lastCategoryRow;
	var indexCounter = 0;
	var rowIndex = childRowObject.rowIndex;
	var parentLevel = parseInt($(childRowObject).attr("level"), 10) - 1;
	
	rows.each(function() {
			  if(indexCounter >= rowIndex) {
				return false;
			  }
			  ++indexCounter;
			  
			  var row = $(this);
			  var qID = row.attr("quickenID");
			  var currentLevel = parseInt(row.attr("level"), 10);
			  
			  //Must be a category and have the correct level
			  if((IsACategoryID(qID) || IsUncategorizedID(qID)) && (currentLevel == parentLevel))
			  {
				lastCategoryRow = row;
			  }
			  });
	
	return lastCategoryRow;
}

// Passing back the value "Total" for colDate will cause the corresponding
// Category Explorer to show the full date range of the report filter.
// Passing null for colDate will show all dates in the Category Explorer.
function CategoryRowClicked(categoryQuickenID, colDate, isExpense)
{
	if( window.viewController )
		window.viewController.ExploreCategoryWithQuickenIDs(categoryQuickenID, colDate, isExpense);		  
}

function CloseAllRows(animated) {
	var rows = $('#tableData tbody tr.level0');
	_CloseRows(rows, animated, true);
	var rows = $('.tableFixedData tbody tr.level0');
	_CloseRows(rows, animated, true);
}

function _ChildRows(rows, allLevels) {
	if (0 == rows.length)
		return;
	var allRows = $($(rows[0]).parent().find("tr"));
	var childRows = [];
	
	rows.each(function () {
		var element = $(this);
		var level = parseInt(element.attr('level'));
		
		var index = $.inArray(this, allRows);
		for (var i = index + 1; i < allRows.length; ++i) {
			var testRow = allRows[i];
			var testLevel = parseInt($(testRow).attr('level'));
			if (testLevel <= level)
				break;
			if (allLevels || testLevel == level + 1)
				childRows.push(testRow);
		}
	});

	return $(childRows);	
}

function _OpenChildRows(rows) {
	var childRows = _ChildRows(rows);
	var allChildren = [];
	childRows.each(function() {
		allChildren.push(this);
		var element = $(this);
		if (element.hasClass("opened"))
			allChildren = $.merge(allChildren, _OpenChildRows(element));
	});
	return $(allChildren);
}

// [DE1827] - Lane Roathe - can't use rows.animate because the animation
//							which hides/shows the rows happens after printing
function _ShowHideRows(rows, show, animated) {
	rows.each(function () {
		this.style.display = show ? '' : 'none';
	});
}

function _ShowRows(rows, animated) {
	_ShowHideRows(rows, true, animated);
}

function _HideRows(rows, animated) {
	_ShowHideRows(rows, false, animated);
}

function _OpenRow(row, animated, storeState) {
	var childRows = _OpenChildRows(row);
	_ShowRows(childRows, animated);
	
	if (row.hasClass("closed"))
		row.toggleClass("closed").toggleClass("opened");
	
	if(storeState && window.viewController)
	{
		var stateID = _GenerateRowID(row);
		window.viewController.SetTableState(stateID, "opened");
	}
}

function _GenerateRowID(row)
{
	var firstTD = row.find("td:first");
	var stateID = firstTD[0].textContent + '_' + row.attr("quickenID");
	
	return stateID;
}

function _CloseRow(row, animated, storeState) {
	var childRows = _ChildRows(row, true);
	_HideRows(childRows, animated);
	
	if(storeState && window.viewController)
	{
		childRows.each(function() {
					   var stateID = _GenerateRowID($(this));
					   window.viewController.SetTableState(stateID, "closed");
					   });
	}
					   
	
	if (row.hasClass("opened"))
		row.toggleClass("opened").toggleClass("closed");
	
	if(storeState && window.viewController)
	{
		var stateID = _GenerateRowID(row);
		window.viewController.SetTableState(stateID, "closed");
	}
}

function _OpenRows(rows, animated, childrenIncluded, storeState) {
	if (0 == rows.length) return;
	
	rows.each(function() {
		_OpenRow($(this), animated, storeState);
	});
	
	if (childrenIncluded)
		_OpenRows(_ChildRows(rows, false), false, childrenIncluded, storeState);
}

function _CloseRows(rows, animated, childrenIncluded, storeState) {
	if (0 == rows.length) return;
	
	rows.each(function() {
		_CloseRow($(this), animated, storeState);
	});
	
	if (childrenIncluded)
		_CloseRows(_ChildRows(rows, false), false, childrenIncluded, storeState);
}
