/* table.js
 * Code to support the recent searches tables. 
 * ------------------------------------------------------------------------ */



var STABLE =
{
  /*
  vtable_ : array of urls initialized in slist.jj2
  searches_ : list of sids used to fetch metrics for each search
  curpage_ : tracks current page position
  fetcher_ : keep last used request url
  cursortfield : tracks current sort field
  cursortorder : tracks current sort order (asc / desc)
  curoffset : tracks offset used to fetch different pages
  */
  vtable_ : null,
  searches_ : null,
  curpage_ : 1,
  fetcher_ : null,
  cursortfield : 'startdate',
  cursortorder : 'desc',
  curoffset : 0,

  init : function(vtable) {
    STABLE.vtable_ = vtable;
    STABLE.load_my_searches(STABLE.set_content_json);    
    // Add click handlers for each sortable column
    $('#your-searches > table > thead > tr > th.sortable').click(STABLE.sort_table_with_field);
  },


  /* Pass in an array of search ID values.  STABLE will then take care
     of calling /searches/metrics on each one and updating the table. */
  gather_metrics : function(sidlist) {
    STABLE.searches_ = sidlist;
    STABLE.searches_.reverse();
    STABLE.next_metric();
  },


  /* Private function used to get metrics for each search incrementally. */
  next_metric : function() {
    if (STABLE.searches_ && STABLE.searches_.length > 0) {
      var m = STABLE.searches_.pop();
      $.getJSON(STABLE.vtable_.metrics + '/' + m, STABLE.next_metric_return);
    }
  },


  /* getJSON callback is called with JSON object from /searches/metrics. */
  next_metric_return : function(data) {
      STABLE.next_metric();
	  /* Quick & Dirty trending: compare todays count with average
	     daily count over last week. */
	  var avg = (data.week/7.0);
	  var cls = 'no-trend';
	  if (data.day > avg) {
	    cls = 'up-trend';
	  }
	  else if (data.day < avg) {
	    cls = 'down-trend';
	  }
	  $("#sr_" + data.sid + "_t").addClass(cls);
  },

  save_search : function(id) {
    $.getJSON(STABLE.vtable_.save + "/" + id,
              function(data) {
                STABLE.load_recent_searches(STABLE.set_content_json);
              });
  },

  confirm_drop_search : function(id) {
    var remove_button = $('#remove' + id)[0];
    remove_button.style.display = 'none';
    var confirm_div = document.createElement('div');
    confirm_div.id = 'confirm' + id;
    confirm_div.innerHTML = 'are you sure? <a class="confirm-text delete-text" onClick="STABLE.drop_search(' + id + ')">yes</a> | ' + '<a class="confirm-text" onClick="STABLE.restore_remove_button(' + id + ')">no</a>';
    remove_button.parentNode.appendChild(confirm_div);
  },


  restore_remove_button : function(id) {
     var confirm_div = $('#confirm' + id)[0];
     confirm_div.parentNode.removeChild(confirm_div);
     $('#remove' + id)[0].style.display = "";
   },


  drop_search : function(id) {
    $.post(STABLE.vtable_.drop + "/" + id,
              function(data) {
                var selid = BUTTONSET.get_selected_id();
                STABLE.load_my_searches(STABLE.set_content_json);
                var savedropbutton =  $('#savedrop');
                //The button isn't always on the page but your_account tab is.
                if(savedropbutton.length > 0) {
                    //update the save/drop button on main page to reflect changes
                    savedropbutton.replaceWith('<button id="savedrop" value="Save This Search" class="save-search orangeButton" onclick="saveSearch()"><span>Save this Search</span></button>');
                    is_saved = 0;
                }
              });
  }, 

  load_trending_searches : function() {
    STABLE.loading();
    $.get(STABLE.vtable_.trending,
          {'nocache': (new Date()).getTime()},
          function(data, status) {
            STABLE.set_content_json(data);
            STABLE.curpage_ = 1;
            STABLE.fetcher_ = STABLE.vtable_.trending;
          });
  },
  
  /* Loads user saved search list, used only on first time load */
  load_my_searches : function(callback) {
    STABLE.loading();
    STABLE.reset_table_headers();
    $.ajax({
        type: "GET",
        url: STABLE.vtable_.myjson + '/' + STABLE.curoffset + '/' + STABLE.cursortfield + '/' + STABLE.cursortorder,
        data:  {'nocache': (new Date()).getTime()},
        dataType: "json",
        success: function(data, status) {
                     // Clear out arrows on other fields
                     $('#your-search > table > thead > tr > th').removeClass('active-column-desc active-column-asc');
                     $('.startdate').addClass('active-column-desc');
                     STABLE.curpage_ = 1;
                     STABLE.fetcher_ = STABLE.vtable_.myjson;
                     BUTTONSET.select($('#my-searches-btn'));
                     callback(data);
                 }
    });
  },

  /* loads all recent searches, used on first load only */
  load_recent_searches : function(callback) {
    STABLE.loading();
    STABLE.reset_table_headers();
    $.ajax({
        type: "GET",
        url: STABLE.vtable_.recentjson + '/' + STABLE.curoffset + '/' + STABLE.cursortfield + '/' + STABLE.cursortorder,
        data:  {'nocache': (new Date()).getTime()},
        dataType: "json",
        success: function(data, status) {
                     // Clear out arrows on other fields
                     $('#your-searches > table > thead > tr > th').removeClass('active-column-desc active-column-asc');
                     $('.startdate').addClass('active-column-desc');
                     STABLE.curpage_ = 1;
                     STABLE.fetcher_ = STABLE.vtable_.recentjson;
                     BUTTONSET.select($('#recent-searches-btn'));
                     callback(data);
                 }
    });
  },
    
  /* Resets table headers to initial state, used when toggling between recent/my searches */
  reset_table_headers: function() {
    // Reset search field , type and offset
    STABLE.cursortfield = "startdate";
    STABLE.cursortorder = "desc";
    STABLE.curoffset = 0;
    // Reset headers to correct ordering. This should be the same as in template
    $('#your-searches > table > thead > tr > th.sortable').removeClass('asc desc').addClass('desc');
    // Since startdate is a special case, toggle next state to asc
    $('.startdate').removeClass('desc').addClass('asc');
  },

  /* Determines which field was clicked and reloads the table */
  sort_table_with_field: function() {
    // Clear out arrows on other fields
    $('#your-searches > table > thead > tr > th').removeClass('active-column-desc active-column-asc');
    /*  1) Check the clicked column header
        2) Check the order to sort by
        3) Send request and render new table
        4) Toggle order for next request
        5) Update direction arrow to indicate sort order and field
    */
    if($(this).hasClass('startdate')) {
      STABLE.cursortfield = 'startdate';
      if($(this).hasClass('asc')) {
        // Toggle the sort order
        STABLE.cursortorder = 'asc';
        STABLE.send_sort_request(STABLE.set_content_json);
        $(this).removeClass('asc').addClass('desc');
        $(this).addClass('active-column-asc');
      }
      else if($(this).hasClass('desc')) {
        STABLE.cursortorder = 'desc';
        STABLE.send_sort_request(STABLE.set_content_json);
        $(this).removeClass('desc').addClass('asc');
        $(this).addClass('active-column-desc');
      }
    }
    else if($(this).hasClass('name')) {
      STABLE.cursortfield = 'name';
      if($(this).hasClass('asc')) {
        STABLE.cursortorder = 'asc';
        STABLE.send_sort_request(STABLE.set_content_json);
        $(this).removeClass('asc').addClass('desc');
        $(this).addClass('active-column-asc');
      }
      else if($(this).hasClass('desc')) {
        STABLE.cursortorder = 'desc';
        STABLE.send_sort_request(STABLE.set_content_json);
        $(this).removeClass('desc').addClass('asc');
        $(this).addClass('active-column-desc');
      }
    }
  },

  /* Handles all requests after initial load, mostly fetching recent searches and my searches */
  send_sort_request : function(callback) {
    STABLE.loading();
    // Query and set contenta
    $.ajax({
        type: "GET",
        url: STABLE.fetcher_ + '/' + STABLE.curoffset + '/' + STABLE.cursortfield + '/' + STABLE.cursortorder,
        data: {'nocache': (new Date()).getTime()},
        dataType: "json",
        success: callback
    });
  },

  loading : function() {    
    STABLE.searches_ = null;
    // Loading animation starts here
    $("#your-searches > table > tbody").empty();
    var collength = $('#your-searches > table > thead').length;
    $("#your-searches > table > tbody").append("<tr><td style=\"text-align:center\" colspan=\"" + collength + "\"><img alt=\"Loading\" src=\"images/ajax-loader.gif\"/></td></tr>");
  },


  /* fetches and repopulates the table */
  set_content_json : function(result, status) {
    if(typeof(result) == 'object') {
        // Check status variables for error
        if(parseInt(result.status, 10) == 200 && result.errormsg == 'none' && parseInt(result.resultcount, 10) > 0) {
            // Load searches into table
            $("#your-searches > table > tbody").empty();
            // Keep a list of sid for fetching metrics.
            var sidlist = []; 
            for (var i = 0; i < parseInt(result.resultcount, 10); i++) {
                // List of field values to show on page
                var createdate = result.data[i].fromdate;
                var sid = result.data[i].sid;
                sidlist.push(sid);
                var searchlink = STABLE.vtable_.show + '/' + sid;
                var searchname = result.data[i].searchname;
                var keyword = result.data[i].query_html;
                var search_saved = parseInt(result.data[i].saved, 10);

                var resultrow = $('<tr></tr>');
                var onerow = $("<td></td>");
                var slink = $("<a title=\"" + keyword + "\" href=\"" + searchlink + "\">" + searchname + "</a>");
                slink.tooltip({
                    track: true,
                    delay: 0,
                    showURL: false,
                    fade: 250
                });
                onerow.append(slink);
                resultrow.append(onerow);
                resultrow.append("<td><span id=\"sr_" + sid + "_t\">&nbsp;</span></td>");
                resultrow.append("<td>" + createdate + "</td>");
                //Check if twitter user is logged in
                if(parseInt(result.loggedin, 10) === 1) {
                    //if twitter account logged in, then render save/remove button
                    if(search_saved == 1) {
                        // Adding css class ui-corner-three-all messes up formatting in IE7
                        resultrow.append("<td><button id=\"remove" + sid + "\"" + 
                                                "class=\"delete-button ui-corner-three-all\"" + 
                                                "onclick=\"STABLE.confirm_drop_search(" + sid + ")\">Remove Search</button></td>");

                    }
                    else {
                        resultrow.append("<td><button id=\"remove" + sid + "\"" +  
                                                "class=\"save-button ui-corner-three-all\"" + 
                                                "onclick=\"STABLE.save_search(" + sid + ")\">Save Search</button></td>");
                    }
                }
                else {
                    // if a guest is visiting, render a placeholder
                    resultrow.append("<td>&nbsp;</td>");
                }

                $("#your-searches > table > tbody").append(resultrow);
            }
            // Fetch metrics for each sid in sidlist
            // Updates metrics for each search. Not used currently
            STABLE.gather_metrics(sidlist);
        }
        else {
            //otherwise no results were found, show a message indicating so
            $("#your-searches > table > tbody").empty();
            if(parseInt(result.status, 10) == 500) {
                // 500 means something went wrong during querying
                $("#your-searches > table > tbody").append("<tr><td>Server Error: " + result.errormsg + "</td></tr>");
            }
            else {
                // otherwise error is usually just no results
                $("#your-searches > table > tbody").append("<tr><td>" + result.errormsg + "</td></tr>");
            }
        }
    }
    /* count the rows and update the x-y display. */

    /* XXX This is a hack.... we count the rows by counting the 
       number of tcount class elements. 
    
    Paging is NOT used at the moment

    var low = ((STABLE.curpage_ - 1) * 10) + 1;
    var high = (low - 1) + $(".tcount").length;
    if (high === 0) {
      $("#pn-hilow").html("...");    
    }
    else {
      $("#pn-hilow").html(low + " - " + high);    
    }
    */
  },

  next_page : function() {
    var scount = $("#searchtotal").html() * 1;
    if (scount > (STABLE.curpage_ * 10)) {
      STABLE.goto_page(STABLE.curpage_ + 1);
    }
  },

  prev_page : function() {
    var scount = $("#searchtotal").html() * 1;
    if ((scount > 0) && (STABLE.curpage_ > 1)) {
      STABLE.goto_page(STABLE.curpage_ - 1);
    }
  },

  /* Fetches the next set of searchs while keeping sort order and field */
  goto_page : function(pn) {
    STABLE.loading();
    if (! pn) {
      pn = $("#pagenumber")[0].value;
    }
    $.ajax({
        type: "GET",
        url: STABLE.fetcher_ + '/' + ((pn - 1) * 10) + '/' + STABLE.cursortfield + '/' + STABLE.cursortorder,
        data: {'nocache': (new Date()).getTime()},
        dataType: "json",
        success: function(data, status) {
                    STABLE.curpage_ = pn * 1;
                    STABLE.curoffset = (pn - 1) * 10;
                    STABLE.set_content_json(data);
                 }
    });
  },

  /* Update the various total displays on the screen. */
  update_total : function(n) {
    $("#searchtotal").html(n);
    $("#pn-total").html(n);
  }

};

var list = {
	/*
		username : The username of the logged in user.
		parameterList : Array of json urls initialized in slist.jj2
		createdListsArray : Array of the names of the lists created by the user.
		followingListsArray : Array of the names of the lists followed by the user.
		followersListsArray : Array of the names of the lists following the user.
		countJsonParses : Counts number of times the json objects are being parsed.
		max_countJsonParses : Change this based on number of ajax calls.
	*/
	username: '',
	parameterList: null,
	createdListsArray: null,
	followingListsArray: null,
	followersListsArray: null,
	countJsonParses: 0,
	max_countJsonParses: 3,
	busy: false,

  /* Initialize list object. */
  init : function(parameterList) {
	list.createdListsArray= [];
	list.followingListsArray= [];
	list.followersListsArray= [];
	list.parameterList = parameterList;
	list.load_lists();
	list.countJsonParses = 0;
	list.busy= false;
  },

  /* 
  load_lists function performs ajax load and calls update function to update page after all
 3 json objects have been successfully parsed. 
  */
  load_lists : function() {

	//To prevent constant firing of "reload button and prevent raise conditions."
	if ( list.busy ){
		return;
	}
	
	list.busy=true;

	// An internal helper function to convert names.
	function convertNames(full_name, user_name){
		//If the username exists in the full name of the list, return the full name.
		if (full_name.substring(0, user_name.length + 1) != ('@' + user_name)){
			return full_name;
		}
		//If not, remove the username from the full name.
		else{
			return full_name.substring(user_name.length+2);
		}
	}

	list.createdListsArray= [];
	list.followingListsArray= [];
	list.followersListsArray= [];
	list.countJsonParses = 0;
		
    $.getJSON(list.parameterList.created_lists,function(data) { 
		resultSet ='';
		if (data.lists){
			$.each(data.lists, function(i,lists){
				var authorListPair = [];
				authorListPair.push(lists.slug);
				authorListPair.push(lists.user.screen_name);
				authorListPair.push(convertNames(lists.full_name, list.parameterList.username));
				list.createdListsArray.push(authorListPair);
			});
		}
		list.countJsonParses++;
		if (list.countJsonParses == list.max_countJsonParses){
			list.update();
		}
	});

    $.getJSON(list.parameterList.followings_lists,function(data) {
		resultSet ='';
		if (data.lists){
			$.each(data.lists, function(i,lists){
				var authorListPair = [];
				authorListPair.push(lists.slug);
				authorListPair.push(lists.user.screen_name);
				authorListPair.push(convertNames(lists.full_name, list.parameterList.username));
				list.followingListsArray.push(authorListPair);
			});
		}
		list.countJsonParses++;
		if (list.countJsonParses == list.max_countJsonParses){
			list.update();
		}
	});

    $.getJSON(list.parameterList.followers_lists,function(data) {
		resultSet ='';
		if (data.lists){
			$.each(data.lists, function(i,lists){
				var authorListPair = [];
				authorListPair.push(lists.slug);
				authorListPair.push(lists.user.screen_name);
				authorListPair.push(convertNames(lists.full_name, list.parameterList.username));
				list.followersListsArray.push(authorListPair);
			});
		}
		list.countJsonParses++;
		if (list.countJsonParses == list.max_countJsonParses){
			list.update();
		}
	});
	},

	/*
	Update function reads three arrays which were created by parsing json objects,
	then it constructs a sting of HTMl code for the table displaying lists. Then it passes
	the html string to the html page.
	*/
	update : function() {

	$('#your-lists > div > ul').empty();
	
	var maxRows = Math.max(list.createdListsArray.length, list.followingListsArray.length, list.followersListsArray.length);

	for(i=0; i < maxRows; i++){

	        var resultrowCreated = $('#lists-created > ul');
            	if (i < list.createdListsArray.length){
			resultrowCreated.append("<li><a class='list-link' href='" + list.parameterList.save_list + encodeURI(list.createdListsArray[i][1])+ "/" + encodeURI(list.createdListsArray[i][0]) + "'>" + list.createdListsArray[i][2] + "</a></li>");
		}
		else{
			resultrowCreated.append("<li></li>");
		}
		
		var resultrowYouFollow = $('#you-follow > ul');
		if (i < list.followingListsArray.length){
			resultrowYouFollow.append("<li><a class='list-link' href='" + list.parameterList.save_list + encodeURI(list.followingListsArray[i][1])+ "/" + encodeURI(list.followingListsArray[i][0]) +"'>" + list.followingListsArray[i][2] + "</a></li>");
			
		}
		else{
			resultrowYouFollow.append("<li></li>");
		}
		
		var resultrowFollowYou = $('#follow-you > ul');
		if (i < list.followersListsArray.length){
			resultrowFollowYou.append("<li><a class='list-link' href='" + list.parameterList.save_list + encodeURI(list.followersListsArray[i][1])+ "/" + encodeURI(list.followersListsArray[i][0]) +"'>" + list.followersListsArray[i][2] + "</a></li>");
		}
		else{
			resultrowFollowYou.append("<li></li>");
		}

		if (i == (maxRows - 1)){
			$("#table-refresh-lists").html("<table><tr><td colspan=\"3\" align=\"right\"><button id=\"reload\" onclick=\"list.clearCache();\">Reload</button></td></tr></table>");
			list.busy=false;
		} 
	}
  },
	/*
	clearCache function deletes all caches for the list names.
	*/
	clearCache : function () {
		$.post(list.parameterList.reloadlist, function(data) {
			list.load_lists();
		});
	}
};
