// Tennis.js - tennis microsite javascript functions.
// 
// Copyright (c) Betfair 2007. All rights reserved.

// requires jQuery 1.1.2

var Tennis = {
  currentMatchId: null,
  
  selectTab: function(tabName) {
    var selector = "ul#main_tabset li#" + tabName,
        tab      = $(selector);
    
    if (tab) {
      tab.addClass("selected");
      tab.siblings().removeClass("selected");
    }
  },
  
  displayContent: function(contentName) {
    var div = $("div#" + contentName);
    
    div.siblings().hide();
    div.show();
  },
  
  // View statistics for matchId. If matchId is not given, stats will be shown for the
  // currently highlighted match.
  viewStatistics: function(matchId) { Tennis.viewMatchInfo("statistics", matchId); },
  
  // View markets for matchId. If matchId is not given, markets will be shown for the
  // currently highlighted match. 
  viewMarkets: function(matchId) { Tennis.viewMatchInfo("markets", matchId); },
  
  viewMatchInfo: function(type, matchId) {
    var randomInteger = Math.round(Math.random() * 10000);
    
    Tennis.currentMatchId = matchId || Tennis.currentMatchId;
    
    // Apply highlighting to the new match if necessary:
    if (matchId) { Tennis.highlightMatch(matchId); }
    
    $.ajax({
      type:     "GET",
      url:      Config.AS_URL,
      dataType: "html",
      data:     {"defeat_caching": randomInteger, "action": (type + "_xhr"), "match_id": Tennis.currentMatchId},
      success:  function(html) {
        $("div#" + type + "_content").empty().append(html);
        Tennis.selectTab(type + "_tab");
        Tennis.displayContent(type + "_content");
        Tennis.reportClick(this.url);
      }
    });
    
    // Jump to the top of the page, as occasionaly the user may be scrolled
    // out of view of the right tab content.
    document.location = "#";
  },
  
  // Add highlight class to the match listing corresponding to matchId.
  highlightMatch: function(matchId) {
    $("table#upcoming_matches tr").removeClass("highlight2").removeClass("highlight3");
    $("tr#upcoming_match_" + matchId + "_1").addClass("highlight2");
    $("tr#upcoming_match_" + matchId + "_2").addClass("highlight3");
  },
  
  search: {
    initialize: function() {
      $("form[@name=player_search]").submit(function() {
        Tennis.search.byPlayerName( document.getElementById("search_query").value );
        recordStat('TUMGO');
        return false;
      });
    },
    
    byPlayerName: function(query) {
      var players, queryRe, results, matchId;
      
      if (query.length > 0) {
        players = $("td.player_name a");
        queryRe = new RegExp( "(^|\s+)" + query.toLowerCase() );
        results = [];
        
        results = $.grep(players, function(player) {
          return queryRe.test( $.trim(player.innerHTML.toLowerCase()) );
        });
        
        $("tr.match").hide();
        
        $(results).each(function() {
          matchId = ( $(this).parents("tr").attr("match_id") );
          $("tr[@match_id=" + matchId + "]").show();
        });
        
        $("div#clear_search_results").show();
      } else {
        Tennis.search.clearSearchResults();
      }
    },
    
    // Remove the clear search results link, empty the contents of the search
    // query input box, and then display all matches.
    clearSearchResults: function() {
      $("div#clear_search_results").hide();
      $("input#search_query").val("");
      $("tr.match").show();
    }
  },
  
  filter: {
    // Assigns on onSubmit event handler to the filter form.
    initialize: function() {
      $("form[@name=match_filter]").submit(function() {
        Tennis.filter.apply();
        recordStat('TUMGO');
        return false;
      });
    },
    
    // The event handler for the filter form.
    apply: function() {
      var date         = document.getElementById("match_date").value,
          tnmt_comp_id = document.getElementById("tnmt_comp_id").value,
          results      = $("td.match_start_time"),
          matchIdRegexp = /\d+$/,
          matchId;
      
      if (date.length > 0) {
        results = $.grep(results, function(item) {
          return $(item).find("span.match_date").text() === date;
        });
      }
      
      if (tnmt_comp_id.length > 0) {
        results = $.grep(results, function(item) {
          return $(item).find("span.tnmt_comp_id").text() === tnmt_comp_id;
        });
      }
      
      $("table#upcoming_matches tr.match").hide();
      
      $(results).each(function() {
        matchId = matchIdRegexp.exec(this.id)[0];
        $("tr#upcoming_match_" + matchId + "_1").show();
        $("tr#upcoming_match_" + matchId + "_2").show();
      });
      
      Tennis.matches.restripeTable($("table#upcoming_matches"));
    }
  },
  
  // Surface filters are the <select> elements used to filter recent form entries
  // open the statistics screen by surface (Clay, Hard, Grass, Carpet).
  surfaceFilters: {
    // Event handler for the surface filter <select> onchange event.
    updatePage: function(selectElement) {
      var optionValue = selectElement.value.split("-"),
          playerId    = optionValue[0],
          surface     = optionValue[1],
          parameters;
      
      parameters = { "action": "recent_form", "player_id": playerId };
      if (surface) { parameters.surface = surface; }
      
      $.ajax({
        type:     "GET",
        url:      Config.AS_URL,
        data:     parameters,
        dataType: "html",
        success:  function(html) {
          $("table#recent_form_" + playerId + " tbody").before(html).remove();
        }
      });
    }
  },
  
  matches: {
    timestamp: null,
    
    update: function(initialTimestamp) {
      setInterval(function() {
        var randomInteger = Math.round(Math.random() * 10000);
        
        $.getJSON(Config.AS_URL, {
          "action": "matches_update",
          "after": (Tennis.matches.timestamp || initialTimestamp),
          "defeat_caching": randomInteger
        }, function(json) {
          // Update live match scores:
          $(json.matches).each(function() {
            var match          = this,
                matchRows      = [document.getElementById("upcoming_match_" + this.match_id + "_1"),
                                  document.getElementById("upcoming_match_" + this.match_id + "_2")],
                liveMatchTable =  document.getElementById("live_match_" + this.match_id),
                names, serverIndicators;
            
            // Update match scores and matched amount values:
            matchRows = $(matchRows);
            if (matchRows[0] && matchRows[1]) { Tennis.matches.updateScores(matchRows, match); }
            
            // Update the live match table, if present:
            if (liveMatchTable) {
              liveMatchTable = $(liveMatchTable);
              
              Tennis.matches.updateScores(liveMatchTable, match);
              
              // Update the current server status for live matches:
              serverIndicators = liveMatchTable.find("img.server");
              serverIndicators.hide();
              if (match.curr_server_pos == (1 || 3)) { $(serverIndicators[0]).show(); }
              if (match.curr_server_pos == (2 || 4)) { $(serverIndicators[1]).show(); }
            }
            
            // Update the current server indicator:
            serverIndicators = matchRows.find("img.server");
            serverIndicators.hide();
            
            if (match.curr_server_pos) {
              if ( match.curr_server_pos == (1 || 3) ) { $(serverIndicators[0]).show(); }
              if ( match.curr_server_pos == (2 || 4) ) { $(serverIndicators[1]).show(); }
            }
          });
          
          // Update live prices:
          $(json.markets).each(function() {
            var market = this, matchedAmount, marketsMatchedAmount;
            
            // Update the matched amount value:
            matchedAmount = document.getElementById("matched_amount_" + market.market_id);
            
            if (matchedAmount) {
              matchedAmount = $(matchedAmount);
              matchedAmount.text("GBP: " + market.matched_amount);
              // This attribute is used to sort the table:
              matchedAmount.attr("mtch_amt", market.matched_amount_raw);
            }
            
            // Update the matched amount value in the markets tab (if present):
            marketsMatchedAmount = document.getElementById("markets_matched_amount_" + market.market_id);
            if (marketsMatchedAmount) { $(marketsMatchedAmount).text(market.matched_amount); }
            
            $(market.runners).each(function() {
              // Update the runner prices, if present on the page:
              Tennis.matches.updatePrices(this, "match");
              
              // We also want to update the match odds prices in the markets tab, if they are present:
              Tennis.matches.updatePrices(this, "markets");
            });
          });
          
          // Update the timestamp:
          Tennis.matches.timestamp = json.after;
        });
      }, 20 * 1000);
    },
    
    updateScores: function(rows, match) {
      var thisScore, thisSetScore, matchedAmount,
          inPlayImage = rows.find("img.in_play");
      
      // Update the in-play status icon:
      if (inPlayImage) {
        if (match.status === "P") {
          inPlayImage.show();
        } else {
          inPlayImage.hide();
        }
      }
      
      // If the match has started and the result is not a bye or walkover:
      if (match.status !== "N" && match.result_type !== "B" && match.result_type !== "W") {
        // Update game scores for each set:
        rows.find("td.score").each(function(index) {
          thisScore = match.scores[index];
          if (thisScore !== null) {
            this.innerHTML = thisScore;
          } else {
            this.innerHTML = "";
          }
        });
        
        // Update set scores:
        rows.find("td.set_score").each(function(index) {
          thisSetScore = match.set_score[index];
          if (thisSetScore != null) { this.innerHTML = ("(" + (thisSetScore) + ")"); }
        });
      }
      else if (match.result_type == "B" || match.result_type == "W") {
        rows.find("td.score")[0].innerHTML = '<span class="other-result">' + (match.result_type == "W" ? "Walkover" : "Buy") + '</span>';
      }
    },
    
    // Update price information using the given runner. The prefix is the string
    // used to guarantee that the DOM ID corresponding to the runner is unique.
    updatePrices: function(runner, prefix) {
      var back, lay;
      
      back = document.getElementById(prefix + "_runner_" + runner.runner_id + "_back");
      lay  = document.getElementById(prefix + "_runner_" + runner.runner_id + "_lay");
      if (back) { back.innerHTML = runner.back || "&nbsp;"; }
      if (lay)  { lay.innerHTML  = runner.lay  || "&nbsp;"; }
    },
    
    restripeTable: function(table) {
      var rows = $("tr:visible", table);
      
      for (var i = 1; i < rows.length; i+=4) {
        $(rows[i]).addClass('row_0');
        $(rows[i+1]).addClass('row_0');
        $(rows[i+2]).filter('.row_0').removeClass('row_0');
        $(rows[i+3]).filter('.row_0').removeClass('row_0');
      }
    }
  },
  
  markets: {
    matchId:    null,
    intervalId: null,
    
    // Update market data for matchId every 30 seconds.
    update: function(compId, matchId) {
      if (Tennis.markets.intervalId) { clearInterval(Tennis.markets.intervalId); }
      
      intervalId = setInterval(function() {
        $.ajax({
          type:     "GET",
          url:      Config.AS_URL,
          data:     {"action": "markets_update", "match_id": matchId, "tnmt_comp_id": compId},
          dataType: "json",
          success: function(json) {
            var matchedAmount;
            
            $(json).each(function() {
              matchedAmount = document.getElementById("markets_matched_amount_" + this.market_id);
              if (matchedAmount) { matchedAmount.innerHTML = this.matched_amount; }
              
              $(this.runners).each(function() {
                Tennis.matches.updatePrices(this, "markets");
              });
            });
          }
        });
      }, (10 * 1000));
      
      // Store the interval id so that it can be cleared later...
      Tennis.markets.intervalId = intervalId;
    }
  },
  
  // Register a page view with google analytics and/or speedtrap.
  reportClick: function(locationString) {
    if (urchinTracker)       { urchinTracker(locationString); }
    if (betFairclient_event) { betFairclient_event("pageLoad", locationString); }
  }
};

$(document).ready(function() {
  // Assign event handlers for tabs where necessary:
  if ( $("ul#main_tabset").length > 0 ) {
    $("ul#main_tabset li#home_tab").click(function() {
      Tennis.selectTab("home_tab");
      Tennis.displayContent("home_content");
      recordStat('TSNHO');
    });
    
    $("ul#main_tabset li#statistics_tab").click(function() {
      if (!Tennis.statsClicked && Tennis.defaultMatchId) {
        Tennis.viewStatistics(Tennis.currentMatchId || Tennis.defaultMatchId);
        Tennis.statsClicked = true;
      } else {
        Tennis.viewStatistics();
      }
      recordStat('TSNST');
    });
    
    $("ul#main_tabset li#markets_tab").click(function() {
      if (!Tennis.marketsClicked && Tennis.defaultMatchId) {
        Tennis.viewMarkets(Tennis.currentMatchId || Tennis.defaultMatchId);
        Tennis.marketsClicked = true;
      } else {
        Tennis.viewMarkets();
      }
      recordStat('TSNMA');
    });
  }
});

// Open a link in a new browser window. Useful as an onclick event handler, e.g.:
// 
//   <a href="http://www.betfair.com" onclick="externalLink(this.href); return false;"></a>
// 
function externalLink(location, options, origin) {
  if (options) {
    window.open(location, "external_link", options);
  } else {
    window.open(location);
  }
  
  if (origin != null) { recordStat(origin); }
}

function write(str) {
  return document.write(str);
}

function select(name, dflt, opt, atts) {

	if (atts == null)
		atts = [];

	var str = "";

	str += "<select name="+name;

	for (var i = 0; i < atts.length; i+=2)
		str += " "+atts[i]+"='"+atts[i+1]+"'";

	str += ">";

	for (var i = 0; i < opt.length; i+=2) {

		str += "<option value=\""+opt[i]+"\"";

		if (opt[i] == dflt)
			str += " selected";

		str += ">"+opt[i+1]+"</option>";
	}
	str += "</select>";

	return str;
}
