// This is the default column index for the APY (can be overridden)
var APY_COLUMN_INDEX = 2;

var SORT_COLUMN_INDEX = APY_COLUMN_INDEX;
var SORT_COLUMN_INDEX_2 = -1;
var MAX_TABLE_ROWS = 15;
var SORT_ASCENDING = false;

var mainSortFn = ts_sort_default;
var secSortFn = ts_sort_default;

//var CURR_ANIM_ROW = 0;
var CURR_RESULT_PAGE = 1;
var NUM_RESULT_PAGES;

function sortTable(columnIndex, dataType, columnIndex2, dataType2, sortField) {
  
 
    if (columnIndex == SORT_COLUMN_INDEX) {
      SORT_ASCENDING = !SORT_ASCENDING;
    } else if (columnIndex == APY_COLUMN_INDEX) {
      // by default, want to sort APY's descending order
      SORT_ASCENDING = false;
    } else {
      SORT_ASCENDING = true;
    }



    SORT_COLUMN_INDEX = columnIndex;
    SORT_COLUMN_INDEX_2 = columnIndex2;

  
    if (NUM_RESULT_PAGES > 4) {
      fadeInTableBusyOverlay(200);
 
      sortResultsServerCall(sortField, SORT_ASCENDING);
      return;
    }
 
    fadeInTableBusyOverlay(100);
 



    /* Get the currently selected/active table */
    var currSelectedTable = $(".result_table_box:visible table.result_table");
    currSelectedTable.hide();
    
    var currTableBody = currSelectedTable.children("tbody");


    /* Disable the headers */
    //deactivateHeaders();


    var tables = $(".result_table_box table.result_table").get();

  
    
    var resultRows = new Array();
    var tbody, trows;
    for (var i=0; i < tables.length; i++) {
	tbody = tables[i].getElementsByTagName("tbody")[0];
	//trows = tbody.getElementsByTagName("tr");
	for (var j=0; j < tbody.rows.length; j++) {
	    //resultRows.push(tbody.rows[j].cloneNode(true));
	    resultRows.push(tbody.rows[j]);
	}

	
	//while (tbody.firstChild) {
	//  tbody.removeChild(tbody.firstChild);
	//}
	

    }
    
    /* Figure out sort function */
    mainSortFn = ts_sort_default;


    if (dataType == "numeric") {
	mainSortFn = ts_sort_numeric;
    } else if (dataType == "rate") {
	mainSortFn = ts_sort_rate;
    } else if (dataType == "string") {
	mainSortFn = ts_sort_default;
    } else if (dataType == "dollars") {
	mainSortFn = ts_sort_dollars;
    } else if (dataType == "term") {
	mainSortFn = ts_sort_term;
    }


    /* Get secondary sort function */
    secSortFn = ts_sort_default;

    if (columnIndex2 != -1) {
	if (dataType2 == "numeric") {
	    secSortFn = ts_sort_numeric;
	} else if (dataType2 == "rate") {
	    secSortFn = ts_sort_rate;
	} else if (dataType2 == "string") {
	    secSortFn = ts_sort_default;
	} else if (dataType2 == "dollars") {
	    secSortFn = ts_sort_dollars;
	} else if (dataType2 == "term") {
	    secSortFn = ts_sort_term;
    }

	
    }

   
    // Sort the results 
    resultRows.sort(ts_sort_master);

   

 
    var j;
    var row_index = 0;
 


    for (var i=0; i< tables.length; i++) {
	tbody = tables[i].getElementsByTagName("tbody")[0];
	removeChildrenFromNode(tbody);


	j = 0;
	var even = false;
	while (j < MAX_TABLE_ROWS && row_index < resultRows.length) {
	    var resultRow = resultRows[row_index];

	    var classString = "";

	    if (even) {
		classString = "even";
	    } 
	    if (j == (MAX_TABLE_ROWS-1) || row_index == (resultRows.length -1)) {
		classString += " last";
	    }
	 
	    resultRow.setAttribute("class", classString);
	    resultRow.setAttribute("className", classString);

	    even = !even;
	    

	    tbody.appendChild(resultRow);
	    row_index++;
	    j++;
	}

    }
    
    //currTableBody.hide();
    currSelectedTable.show();

    
    var overlays = createCascadedTableOverlays();

    // Fade out the spinner overlay
    fadeOutTableBusyOverlay(300);


    fadeOutCascadedTableOverlays(overlays);
  



}



// Returns array of the created overlay
// "start_index" is optional arg
function createCascadedTableOverlays(start_index) {
 
  var currTableBody = $(".result_table_box:visible table.result_table tbody");

  // If "start_index" defined, then only select rows starting from that index
  if (start_index) {
    var currTableRows = currTableBody.children("tr").slice(start_index);
  } else {
    var currTableRows = currTableBody.children("tr");
  }

  /* Make a bunch of overlays covering each table row, store them in array */
  var overlays = new Array();
    
  if ($.browser.mozilla) {

    currTableRows.each( function(i) {
      overlays.push(UI.makeOverlayDivExact( $(this), "#result_table_holder", "white", 0, 0, -1, 0));
    });
  } else if ($.browser.msie) {
    currTableRows.each( function(i) {
      overlays.push(UI.makeOverlayDivExact( $(this), "#result_table_holder", "white",  1, 0, 0, 2));
    });

  } else {
    currTableRows.each( function(i) {
      overlays.push(UI.makeOverlayDivExact( $(this), "#result_table_holder", "white",  0, 0, 0, 0));
    });
  }

  return overlays;

}

/* Fades out cascaded overlays */
function fadeOutCascadedTableOverlays(overlays) {
  // Fade out the overlays, staggered delay timing 
  var delay = 33;
  for (var i = 0; i < overlays.length; i++)  {
    UI.fadeOverlayOutWithDelay(overlays[i], 333, i*delay);
  }

}




/* Helper: gets standard search result parameters from page, makes AJAX Json call */
function sortResultsServerCall(sortField, ascending) {

  data = serverCallInitializeData();
  
  data.sort_field = sortField;
  data.sort_ascending =  ascending;
  data.curr_page = CURR_RESULT_PAGE;
  

  $.getJSON("/ajax/get-result-tables.json", data, doneSortResults);


}

/* Callback */
function doneSortResults(data, textStatus) {
  var tablesHtml = data.result_tables_html;
  var tablesElem = $(tablesHtml);

  $("#result_table_holder").children('div.result_table_box').remove();

  tablesElem.appendTo($("#result_table_holder"));

  var overlays = createCascadedTableOverlays();

  fadeOutTableBusyOverlay(300);
 
  fadeOutCascadedTableOverlays(overlays);


  // Update bank map
  if (map) {
    getLocationData();
  }
}





/**
 * Returns the inner text of an element.
 */
function ts_getInnerText(el) {
    if (typeof el == "string") return el;
    if (typeof el == "undefined") { return el };
    if (el.innerText) return el.innerText;	//Not needed but it is faster
    var str = "";
    
    var cs = el.childNodes;
    var l = cs.length;
    for (var i = 0; i < l; i++) {
	switch (cs[i].nodeType) {
	case 1: //ELEMENT_NODE
	    str += ts_getInnerText(cs[i]);
	    break;
	case 3:	//TEXT_NODE
	    str += cs[i].nodeValue;
	    break;
	}
    }
    return str;
}


/** SORTING FUNCTIONS **/


function ts_sort_master(a,b) {

  
 
    

    if (SORT_COLUMN_INDEX_2 == -1) {

	if (SORT_ASCENDING) {
	    return mainSortFn(a,b,SORT_COLUMN_INDEX);
	} else {
	    return -mainSortFn(a,b,SORT_COLUMN_INDEX);
	}

    } else {
	if (SORT_ASCENDING) {
	    return mainSortFn(a,b,SORT_COLUMN_INDEX) || secSortFn(a,b,SORT_COLUMN_INDEX_2);
	} else {
	    return -mainSortFn(a,b,SORT_COLUMN_INDEX) || secSortFn(a,b,SORT_COLUMN_INDEX_2);
	}
    }


}

/**
 * Sorts strings numerically.
 */
function ts_sort_numeric(a,b,col_index) { 
    aa = parseFloat(ts_getInnerText(a.cells[col_index]));
    if (isNaN(aa)) aa = 0;
    bb = parseFloat(ts_getInnerText(b.cells[col_index])); 
    if (isNaN(bb)) bb = 0;
    return aa-bb;
}

function ts_sort_term(a,b,col_index) { 
    aa_str = ts_getInnerText(a.cells[col_index]);
    aa_term_unit = aa_str.split(" ")[1];
   
    var aa;
    if (aa_term_unit.search(/year/) != -1) {
	aa = parseFloat(aa_str) * 12;
	//document.write(aa_str + "-->" + aa + "</br>");
    } else {
	aa = parseFloat(aa_str);
    }
    if (isNaN(aa)) aa = 0;
   
    bb_str = ts_getInnerText(b.cells[col_index]); 
    bb_term_unit = bb_str.split(" ")[1];

    var bb;
    if (bb_term_unit.search(/year/) != -1) {
	bb = parseFloat(bb_str) * 12;
	//document.write(bb_str + "-->" + bb + "</br>");
    } else {
	bb = parseFloat(bb_str);

    }

    if (isNaN(bb)) bb = 0;

    return aa-bb;

 
}


function ts_sort_rate(a,b,col_index) { 
    return ts_sort_numeric(a,b,col_index);
}

/**
 * Sorts currency in dollars (e.g. $1000)
 */
function ts_sort_dollars(a,b,col_index) { 

    
    aa_text = trim(ts_getInnerText(a.cells[col_index]));
    bb_text = trim(ts_getInnerText(b.cells[col_index]));
   

    if (aa_text.charAt(0) != "$") {
	if (bb_text.charAt(0) != "$") {
	    return 0;
	} else {
	    return 1;
	}
    } else if (bb_text.charAt(0) != "$") {
	return -1;

    }
    


    aa_str = aa_text.substr(1);
    bb_str = bb_text.substr(1);
    

    // Alternate way of getting dollars, requires amount be in "name" attrib
    /*
    aa_str = a.cells[col_index].getAttribute("name");
    bb_str = b.cells[col_index].getAttribute("name");

    if (aa_str == "None") {
	if (bb_str == "None") {
	    return 0;
	} else {
	    return 1;
	}
    } else if (bb_str == "None") {
	return -1;

    }
    */

    aa = parseFloat(aa_str.replace(/,/g, ""));
    if (isNaN(aa)) aa = 0;

    bb = parseFloat(bb_str.replace(/,/g, ""));

    if (isNaN(bb)) bb = 0;
    return aa-bb;
}


/**
 * Sorts strings case insensitively.
 */
function ts_sort_caseinsensitive(a,b,col_index) {
    aa = ts_getInnerText(a.cells[col_index]).toLowerCase();
    bb = ts_getInnerText(b.cells[col_index]).toLowerCase();
    if (aa==bb) return 0;
    if (aa<bb) return -1;
    return 1;
}

/**
 * Sorts strings by the default sort behavior.
 */
function ts_sort_default(a,b,col_index) {
    aa = ts_getInnerText(a.cells[col_index]);
    bb = ts_getInnerText(b.cells[col_index]);
    if (aa==bb) return 0;
    if (aa<bb) return -1;
    return 1;
}

/* Trim function */
function trim(str) {


    //return str.replace(/^\s*|\s*$/,"");
    return str.replace(/^\s+|\s+$/g,"");

}



function removeChildrenFromNode(node)
{


    while (node.hasChildNodes())
	{
	    node.removeChild(node.firstChild);
	}
}


function deactivateHeaders() {
    
    $("table.result_table thead a").removeAttr("onclick");
    //$("table.result_header a").attr("onclick", "return false;");
    $("table.result_table thead a").unbind("click");
}


/* Reshow clickable result table headers */
function activateHeaders() {
  

    $("table.result_table thead td.product_name a").click( function() 
						    {sortTable(0,'string',2,'rate'); return false; } );
    $("table.result_table thead td.bank_name a").click( function() 
						 {sortTable(1,'string',2,'rate'); return false; } );
    
    if (RESULT_TYPE == "DEFAULT") {
	
	$("table.result_table thead td.apy a").click( function() 
					       {sortTable(2,'rate',3,'term'); return false; } );
	$("table.result_table thead td.min_deposit a").click( function() 
						       {sortTable(4,'dollars',2,'rate'); return false; } );
	$("table.result_table thead td.term a").click( function() 
						{sortTable(3,'term',2,'rate'); return false; } );
    } else if (RESULT_TYPE == "DEPOSITS") {
	
	
	$("table.result_table thead td.apy a").click( function() 
					       {sortTable(2,'rate',3,'dollars'); return false; } );
	$("table.result_table thead td.min_deposit a").click( function() 
							 {sortTable(3,'dollars',2,'rate'); return false; } );
	$("table.result_table thead td.max_deposit a").click( function() 
						       {sortTable(4,'dollars',2,'rate'); return false; } );


    }

}

/* Helper: fills out "data" object with standard search info */
function serverCallInitializeData() {
  data = {}

  data.product_type = $("#search_product").val();
  data.search_type = $("#search_type").val();
  data.term = $("#search_term").val();
  data.city = $("#search_city").val();
  data.state  = $("#search_state").val();
  data.zip = $("#search_zip").val();

  if ($("#filter_balance").val()) {
    data.filter_balance = $("#filter_balance").val();
  }

  if ($("#filter_cd_mindeposit").val()) {
    data.filter_cd_mindeposit = $("#filter_cd_mindeposit").val();
  }

  return data;

}



/* Filter deposit results to match a given balance */
function filterResultsForBalance(amount) {

  // Store the filter balance in the hidden <input>
  $("#filter_balance").val(amount);

  filterResultsServerCall();
}

function filterResultsForCDMindeposit(amount) {
  $("#filter_cd_mindeposit").val(amount);
  filterResultsServerCall();  
}

var PRE_FILTER_VISIBLE_PAGES;

/* Helper: gets standard search result parameters from page, makes AJAX Json call */
function filterResultsServerCall() {

  data = serverCallInitializeData();

  $.getJSON("/ajax/get-result-tables.json", data, doneFilterResults);
  
  // Result table might not exist (if currently no results are showing)
  if ($("div.result_table_box").length > 0) {  
    fadeInTableBusyOverlay(200);
  }
  
  var currTableRows = $(".result_table_box:visible table.result_table tbody tr");
  PRE_FILTER_VISIBLE_PAGES = currTableRows.length;

}
 

/* Callback from "filterResultsServerCall()"; gets returned table HTML and places on page */
function doneFilterResults(data, textStatus) {


  var tablesHtml = data.result_tables_html;
  var tablesElem = $(tablesHtml);

  $("#result_table_holder").children('div.result_table_box').remove();
  $("#result_table_holder").children('div.no_results_message').remove();

  tablesElem.appendTo($("#result_table_holder"));

  var numPages = data.num_pages;
  
  // Update global table count 
  NUM_RESULT_PAGES = numPages;
  CURR_RESULT_PAGE = 1;

  // Reset sorting info
  var SORT_COLUMN_INDEX = APY_COLUMN_INDEX;
  var SORT_COLUMN_INDEX_2 = -1;
  var SORT_ASCENDING = false;

  buildResultsNav(numPages);

  fadeOutTableBusyOverlay(300);
 
  /* If new page has more rows than before, fade in boxes over them */
  var currTableRows = $(".result_table_box:visible table.result_table tbody tr");
  if (currTableRows.length > PRE_FILTER_VISIBLE_PAGES) {
    num_new_rows = currTableRows.length - PRE_FILTER_VISIBLE_PAGES;
    var overlays = createCascadedTableOverlays(PRE_FILTER_VISIBLE_PAGES);
    fadeOutCascadedTableOverlays(overlays); 
  }


  // Update bank map
  if (map) {
    getLocationData();
  }
}






/* After doing a filter, rebuild the page number/arrow navigation for results table */
function buildResultsNav(numPages) {
    // Clear all existing page numbers
    
    var result_pages_div = $("#result_pages");
    result_pages_div.empty();
    
    //var result_pages_list= $("#result_pages dl");
    // result_pages_list.remove()

    // If only one page, don't need the numbers
    if (numPages == 1) return;

    var pageItemsList = "<dl>";
    for (var i = 0; i < numPages; i++) {
	pageNum = i + 1;
	pageItemsList += "<dt id='result_page_item_" + pageNum + "'" + "class='result_page_item'>" + 
	    "<a href='#'>" 
	    + pageNum + "</a> </dt> \n";
	
    }
    pageItemsList += "</dl>";
   
    result_pages_div.append(pageItemsList);
    $("#result_pages dt.result_page_item:first").addClass("selected");
    $("#result_pages dt.result_page_item:first").addClass("first");
    $("#result_pages dt.result_page_item:last").addClass("last");

    $("#result_pages dt.result_page_item a").each( function(i) { 
	    $(this).click( function() { 
		    showResultTable(i+1);
		    return false;
		}) 
		});


}


/* Fades in busy overlay over tbody */
function fadeInTableBusyOverlay( speed ) {
  var currTable = $("div.result_table_box:visible").children("table.result_table");
  var tbody = currTable.children("tbody");

  var result_table_overlay = UI.makeOverlayDivExact(tbody, "#result_table_holder", "white", 
                                                 0,0,0,0, 0.7, true);

  result_table_overlay.fadeIn( speed );
  result_table_overlay.addClass('result_table_busy_overlay');
}

/* Fades out busy overlay over tbody */
function fadeOutTableBusyOverlay( speed) {

  $("div.result_table_busy_overlay").fadeOut(speed, function() { $(this).remove();  });
}



/* Navigation between different pages of results */
function showResultTable(toshow) {

  CURR_RESULT_PAGE = toshow;

  $(".result_page_item").removeClass("selected");
  $(".result_table_box").hide();
   

  $("#result_table_box_" + toshow).show();
  $("#result_page_item_" + toshow).addClass("selected");	 

  

  var result_table_body = $("#result_table_box_" + toshow + " table.result_table tbody");


  if ($.browser.mozilla) {

    UI.fadeInOverlayExact(result_table_body, "#result_table_holder", "white", 200, null, 
                       0, 0, -1, -1);
	
  } else if ($.browser.msie) {
    UI.fadeInOverlayExact(result_table_body, "#result_table_holder", "white", 200, null, 
                       1, 0, 0, -1);
  } else {
    UI.fadeInOverlay(result_table_body, "#result_table_holder", "white", 200, null);
			
  }
  
  if (map) {
    getLocationData();
  }
 
}


/* Called when click on "next" button for result table */
function showNextTable() {
  //alert("Curr page:" +  CURR_RESULT_PAGE);

  if (CURR_RESULT_PAGE < NUM_RESULT_PAGES) {
 
    showResultTable(CURR_RESULT_PAGE + 1);
  }
}

function showPrevTable() {
  //alert("Curr page:" +  CURR_RESULT_PAGE);
  if (CURR_RESULT_PAGE > 1) {

    showResultTable(CURR_RESULT_PAGE - 1);
  }

}

function getLocationData() {
    var result_table_body = $("#result_table_box_" + CURR_RESULT_PAGE + " table.result_table tbody")[0];
    var banks = new Array();
    for (var i=0; i<result_table_body.rows.length; i++) {
	curRow = result_table_body.rows[i];
	bank_text = trim(ts_getInnerText(curRow.cells[1]));
	banks[i] = bank_text;
    }

 
    map.clearOverlays();

    var tLat = 0;
    var tLong = 0;
    var n = 0;
    $.post("/ajax/get-locations.json",
	   {banks: banks,
		   state: $("#state").html(),
		   city: $("#city").html(),
		   zip: $("#zip").html()}, 
	   function(j){
	       for (var i = 0; i < j.length; i++) {
		   addMarker(j[i]);
		   tLat = tLat + j[i].lat;
		   tLong = tLong + j[i].lon;
		   n = n + 1;
	       }
	       if (n != 0) {
		   map.setCenter(new GLatLng(tLat/n, tLong/n), 12);
	       }
	   }, 
	   "json");
}

function addMarker( branch) {
    var point = new GLatLng(branch.lat, branch.lon);
    var resultcontent = '<p><b>'+branch.bank + '</b>';
    resultcontent = resultcontent + '<br />' +  branch.address;
    resultcontent = resultcontent + '<br />' + branch.city + ' ' + branch.state;
    if (branch.zip) {
	resultcontent = resultcontent + ', ' + branch.zip;
    }
    if (branch.phone) {
	resultcontent = resultcontent + '<br /><b>Phone:</b> ' +  branch.phone;
    }
    resultcontent = resultcontent +'</p>';
    map.addOverlay(createMarker(point, 1, resultcontent));

}





