/*
 * namco-ui.js --
 *   Common widget functionality
 */

/*
  Feature switcher: 4-game switcher with fading side or bottom info bar
*/
var Switcher = function(args) {
  var currentlySelectedThumb = 0;

  // Assign side thumbnails/links
  for (i = 1; i <= 4; i++) {
    var thumb = $("#featurethumb" + i);
    var thumbLink = thumb.find("a");
    var thumbImg = thumbLink.find("img");
    var array = args[i];
    var thumbImgURL = array.thumbnailImgURL;
    var headlineImgURL = array.headlineImgURL;
    var alt = array.alt;
    var url = array.url;
    var target = array.targetblank;

    // Replace with 'unknown' image if thumbnail/headline img url is blank
    var imgPattern = /(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*\.(?:jpg|gif|png))(?:\?([^#]*))?(?:#(.*))?/

    if (!thumbImgURL.match(imgPattern))
      thumbImgURL = "/images/switcher_unknown_thumb.png";
    if (!headlineImgURL.match(imgPattern))
      headlineImgURL = "/images/switcher_unknown.png";

    if (target) {
      $(thumbLink).attr({
	href: url,
	target:"_blank"
      });
    } else {
      $(thumbLink).attr({href: url});
    }


    $(thumbImg).attr({
      src: thumbImgURL,
      alt: alt,
      title: alt
    });
  }

  // For IE6, Remove <img> and switch to a css bg to fix thumb height issue
  if ($.browser.msie && $.browser.version < 7)
    $(".featurethumb").each(function() {
      var imgURL = $(this).find("img").attr("src");
      $(this).html("");
      $(this).css({backgroundImage: "url(" + imgURL + ")"});
    });

  // Elements are hidden by default; make visible
  $("#featurethumbs, #sideinfo, #bottominfo").css({visibility: "visible"});

  var showFeature = function(featureIndex) {
    // Extract data for switcher from args class parms
    var array = args[featureIndex];
    var featureHeadlineImgURL = array.headlineImgURL;
    var featureTitle = array.title;
    var featureDescription = array.desc;
    var infoLocation = array.infoLocation;
    var targetURL = array.url;
    var linktext = array.linktext;
    var targetblank = array.targetblank;

    if (currentlySelectedThumb != featureIndex) {
      var previouslySelectedThumb = currentlySelectedThumb;

      // Kill any current animations happening from an incomplete hover event
      $("#featurestabs .info").stop();

      // Reset the previous thumbnail thumbnail with a border enabled
      if (previouslySelectedThumb > 0)
	$("#featurestabs #featurethumb" + previouslySelectedThumb).removeClass("selected");

      // Update our global to indicate that this is the selected thumbnail
      currentlySelectedThumb = featureIndex;

      // Change main feature bg image and update side info bar
      $("#featurestabs").css({backgroundImage: "url(" + featureHeadlineImgURL + ")"});

      // Set thumbnail border
      $("#featurestabs #featurethumb" + featureIndex).addClass("selected");

      // Fade out the info bar; replace info data and fade in new info bar
      $("#featurestabs .info").fadeTo(150, 0, function() {
	var info = $("#featurestabs #" + infoLocation + "info");

	info.find(".featuredesc").html(featureDescription);
	if(targetblank==1){
	  info.find(".featuretitle").html("<a href=\"" + targetURL + "\" target='_blank'>" + featureTitle + "</a>");
	  info.find(".linktext").html("<a href=\"" + targetURL + "\" target='_blank'>" + linktext + "</a>");
	} else {
	  info.find(".featuretitle").html("<a href=\"" + targetURL + "\">" + featureTitle + "</a>");
	  info.find(".linktext").html("<a href=\"" + targetURL + "\">" + linktext + "</a>");
	}

	/*info.find(".featuredesc").append(
	  "<a href=\"" + targetURL + "\"><p class=\"playnow\">LEARN MORE</p></a>"
	  );*/
	info.fadeTo(150, 0.8, function() {
	  info.find(".featuretitle").fadeTo(100, 0.8);
	  info.find(".featuredesc").fadeTo(100, 0.8);
	});
      });

      // Go to game page if bg image is clicked
      //$("#featurestabs").click(function() {
      //  window.location.href = targetURL;
      //});
    }
  };

  /*
    Preload images before display; as a callback, assign click/hover to all elements
  */
  var preload = function(callback) {
    for (i = 1; i <= 4; i++) {
      var image = new Image();
      image.src = args[i].headlineImgURL;
    }

    callback();
  };

  // Used for events that stop the timer before displaying the selected feature
  var activateFeature = function(id) {
    if (this.autoCycle)
      clearInterval(this.autoCycle);

    showFeature(id);
  };

  /* Used for events that will reactivate the timer (such as a mouseout)--
     will restart the timer after the specified start interval */
  var activateInterval = function() {
    if (args.autoCycleInterval > 0) {
      this.autoCycle = setInterval(function() {
	if (currentlySelectedThumb < 4)
	  next_index = currentlySelectedThumb + 1;
	else
	  next_index = 1;

	showFeature(next_index);
      }, args.autoCycleInterval);
    }
  };

  preload(function() {
    // Show first item in list, activate feature auto-cycle
    showFeature(1);
    activateInterval();

    /*
      Create mouse over/out events for 4 thumbnails, which stops/starts the auto-cycle, respectively;
      if the user is on an iPhone or iPad (cannot hover over images), use clicking instead of hovering
    */
    if (navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i))
      use_click = true;
    else
      use_click = false;

    $(".featurethumb").each(function(i) {
      if (use_click)
	$(this).click(function() {
	  activateFeature(i + 1);

	  return false;
	});
      else
	$(this).hover(
	  function() { activateFeature(i + 1); },
	  function() { activateInterval(); }
	);
    });
  });
};

/*
  Fade-in interactive tooltip --
  Generates a div with the given ID;
  has the following structure:

  <div id="<id>" class="tooltip">
  <div class="title"></div>
  <div class="image"></div>
  <div class="desc"></div>
  <div class="genre"><p>Genre: <em class="name"></em></p></div>
  <div class="trynow"><form></form></div><!-- < not rendered if there is no try now availability -->
  </div>
*/
var Tooltip = function(id) {

  this.title = "";
  this.thumbnail = "";
  this.desc = "";
  this.genre = "";
  this.position = [0, 0];
  this.namcoOriginal = false;
  this.event = 0;

  var responseCache = {};

  // Remove existing/legacy tooltip divs
  $(document).ready(function() {
    $(id).remove();
  });

  this.show = function(useBounds) {
    // Cleanup
    $(id).remove();
    clearTimeout(this.showTimer); // Flush any existing hover timers

    /* Note that this is not the ideal way to get our game ID,
       though for now it is the only context data available. */
    var gameID = this.thumbnail.split("/").reverse()[1];
    // Replace existing tooltip <div> with AJAX response data
	
	if(id == "#tooltip-mac"){
		if (!responseCache[gameID])
		  $.ajax({
			method: "GET",
			url: "/resources/tooltip_mac.php",
			data: {
			  id: gameID
			},
			async: false,
			dataType: "html",
			success: function(result) {
			  responseCache[gameID] = result;
			}
    	});
	}else{
		if (!responseCache[gameID])
		  $.ajax({
			method: "GET",
			url: "/resources/tooltip.php",
			data: {
			  id: gameID
			},
			async: false,
			dataType: "html",
			success: function(result) {
			  responseCache[gameID] = result;
			}
    	});
	}
    //$(responseCache[gameID]).appendTo("body");
    $(responseCache[gameID]).appendTo("body");
    var tooltip = $(id);

    $(tooltip).css({
      left: this.position[0],
      top: this.position[1] - 10
    });

    $(tooltip).hover(
      function() {
	clearTimeout(Tooltip.hideTimer);
      },
      function() {
	$(tooltip).hide();
      }
    );

    Tooltip.showTimer = setTimeout(function() {
      if ($.browser.msie)
	$(tooltip).show();
      else
	$(tooltip).fadeIn("fast");
    }, 500);
  };

  this.hide = function() {
    clearTimeout(Tooltip.showTimer);
    Tooltip.hideTimer = setTimeout(function() {
      $("#tooltip-pc").hide();
    }, 500);
  };
};

/*
  Dynamic list paginator--
  Given a div, all elements within will be automatically paginated,
  based on the # of elements allowed to be displayed at a time
*/
var Paginator = function(id, showPerPage, pagesToShow) {
  this.currentPage = 1;
  this.showPerPage = showPerPage;
  this.id = id;

  if (pagesToShow)
    this.pagesToShow = pagesToShow;
  else
    this.pagesToShow = 10;  // Default to showing 10 page links max (except first/last page)

  var children = $(id).children();
  var itemCount = children.size();
  var pageCount = Math.ceil(itemCount / showPerPage);
  var pageGroup = {start: 1, end: this.pagesToShow};

  this.show = function(pageIndex) {
    pageIndex = parseInt(pageIndex);

    /*
      Determine if we need to change the displayed page group --
      if on the first page, last page, or at the start/end of the current group
    */
    if (pageIndex == 1) // Is the first page
      pageGroup = {
	start: 1,
	end: this.pagesToShow
      };
    else if (pageIndex == pageCount) // Is the last page
      pageGroup = {
	start: pageIndex - this.pagesToShow,
	end: pageIndex
      };
    else if (pageIndex == pageGroup.start || pageIndex == pageGroup.end)  // Is at the beginning or end of page group
      pageGroup = {
	start: pageIndex - (this.pagesToShow / 2),
	end: pageIndex + (this.pagesToShow / 2)
      };

    var pager = $("#pageselector");
    this.currentPage = parseInt(pageIndex);

    // Clear all previously enabled elements
    children.hide();

    // Show relevant elements, hide those not matching current page
    for (var i = 0; i < itemCount && i < this.showPerPage; i++) {
      elementIndex = i + this.showPerPage * (this.currentPage - 1);

      if (elementIndex < itemCount)
	$(children[elementIndex]).css({display: "block"});
    }

    // Populate the page selector
    pager.html("");

    if (pageCount > 1)
      for (var i = 1; i <= pageCount; i++) {
	var isDisplayed = false;
	var pageLink = document.createElement("div");
	pageLink.id = "pageLink" + i;
	pageLink.className = "pagelink";
	pageLink.paginator = this;
	$(pageLink).click(function() {
	  this.paginator.show($(this).find("p").html());
	})

	if (i == this.currentPage)
	  $(pageLink).addClass("selected");
	else if ((i == 1 || i == pageCount) && pageCount >= this.pagesToShow)
	  $(pageLink).addClass("endpage");

	pageLink.innerHTML = "<p>" + i + "</p>";

	if ((i >= pageGroup.start && i <= pageGroup.end) || i == pageCount || i == 1)
	  pager.append(pageLink);
      }
  };
};

/*
  Genre-based game switcher --
  Retrieves games from AJAX-based resource, based on currently selected genre

  -After a request, it will store a genre's game list in memory, to prevent redundant
  requests and reduce server load.

  -Tooltip will be built based on hidden input data
  (see tooltip div description for required attributes)
*/
var GenreSelector = function(genreList, defaultGenre, gamesContainer, resource, gamesPerPage, tooltip) {

  var selectedGenre = defaultGenre;
  var genreDataCache = {};  // Stores previous genre request data
  var gamesContainer = $(gamesContainer);

  /*
    showGenre(callback)

    Send an AJAX request to the given resource,
    which is a PHP file in the following location and format:
    /resources/[resource].php?genre=[selectedGenre]

    i.e.,
    /resources/pc_games.php?genre=match3

    The PHP script's response is then injected into gamesContainer.
  */

  var showGenre = function(callback) {
      $(".genrecell").removeClass("selected");
    var doShow = function() {
      paginator = new Paginator(gamesContainer, gamesPerPage);
      paginator.show(1);

      /* Assign tooltip click events to each game,
	 from a newly-instantiated Tooltip */
      var localTooltip = this.tooltip;

      localTooltip.useBounds = true;

      var showTooltip = function(e) {
	var gameDiv = $(this).parent().parent();

	// Position adjustment browser fixes
	var adjustLeft = 0;
	var adjustTop = 0;

	if ($.browser.msie && $.browser.version <= 6) {
	  adjustLeft = 220;
	  adjustTop = 565;
	}

	localTooltip.position = [
	  gameDiv.position().left + ($(gameDiv).width() / 2) + adjustLeft,
	  gameDiv.position().top + ((
	    gameDiv.find(".icon").height() // + $(gameDiv).find(".title").height()
	  ) - 5) + adjustTop
	];
	var parentNode = $($(this).parents()[1]);
	var isNamcoOriginal = parentNode.find(".is_namco_original").attr("value");
	localTooltip.desc = parentNode.find(".desc").attr("value");
	localTooltip.thumbnail = parentNode.find("img").attr("src");
	localTooltip.genre = parentNode.find(".genre").attr("value");
	localTooltip.title = parentNode.find(".title a span").html();

	if (isNamcoOriginal)
	  localTooltip.namcoOriginal = true;
	else
	  localTooltip.namcoOriginal = false;

	localTooltip.show();
      }

      var hideTooltip = function() {
	localTooltip.hide();
      }

      $(gamesContainer).children().each(function() {
	$(this).find("a").hover(showTooltip, hideTooltip);
      });

      if (callback) callback();
    };

    // If the genre game data exists in our cache array, load that in place of an AJAX request
    if (genreDataCache[selectedGenre]) {
      gamesContainer.html(genreDataCache[selectedGenre]);
      doShow();
    } else {
      $.get("/resources/" + resource + ".php?genre=" + selectedGenre, function(data) {
	genreDataCache[selectedGenre] = data;
	gamesContainer.html(genreDataCache[selectedGenre]);
	doShow();
      });
    }

    $("#" + selectedGenre).addClass("selected");
  };

  /* Assign click events to each link in the genre listing;
     it will assign the object's selected genre based on the element's ID */
  $(genreList).each(function() {
    $(this).click(function() {

      var pager = $("#pageselector");
      if(this.id != selectedGenre) {
	gamesContainer.stop();
	pager.hide();
	selectedGenre = this.id;

	$(genreList + ".selected").each(function() { $(this).removeClass("selected"); });
	gamesContainer.fadeTo(100, 0.5, function() {  // Show loading appearance
	  showGenre(function() {
	    gamesContainer.fadeTo(200, 1.0);
	    pager.show();
	  });
	});

      } else
	return false;
    });
  });

  // Show default genre on load
  showGenre();
};


var GenreTooltip = function(gamesContainer,genretooltip) {
  /* Assign tooltip click events to each game,
     from a newly-instantiated Tooltip */
  var gamesContainer = $(gamesContainer);
  this.genretooltip = genretooltip;

  var localTooltip = this.genretooltip;

  var showTooltip = function(e) {
    var gameDiv = $(this).parent().parent();
    // localTooltip.position = [
    //   gameDiv.position().left + ($(gameDiv).width() / 2),
    //   gameDiv.position().top + ((
    // 	gameDiv.find(".icon").height() + $(gameDiv).find(".title").height()
    //   ))
    // ];

    // Position adjustment browser fixes
    var adjustLeft = 0;
    var adjustTop = 0;

    if ($.browser.msie && $.browser.version <= 6) {
      adjustLeft = 220;
      adjustTop = 565;
    }

    localTooltip.position = [
      gameDiv.position().left + ($(gameDiv).width() / 2) + adjustLeft,
      gameDiv.position().top + ((
	gameDiv.find(".icon").height() // + $(gameDiv).find(".title").height()
      ) - 5) + adjustTop
    ];
    var parentNode = $($(this).parents()[1]);
    var isNamcoOriginal = parentNode.find(".is_namco_original").attr("value");
    localTooltip.desc = parentNode.find(".desc").attr("value");
    localTooltip.thumbnail = parentNode.find("img").attr("src");
    localTooltip.genre = parentNode.find(".genre").attr("value");
    localTooltip.title = parentNode.find(".title a span").html();
    localTooltip.useBounds = true;

    if (isNamcoOriginal)
      localTooltip.namcoOriginal = true;
    else
      localTooltip.namcoOriginal = false;

    localTooltip.show();
  }

  var hideTooltip = function() {
    localTooltip.hide();
  }

  $(gamesContainer).children().each(function() {
    $(this).find("a").hover(showTooltip, hideTooltip);
  });
}
/*
  Pager to flip through screenshots --
  Requires a set of:  * Selection "buttons" (.screenshotselector -> #screenshotselector[1,2,3,...])
  * Images (.screenshotimg -> #screenshotimg[1,2,3,...])
  * Back/forward arrows -> #screenshotarrowback, #screenshotarrowfwd

  */
var ScreenshotPager = function() {
  var pager = this;
  var pageCount = $(".screenshotimg").size();

  this.currentPage = 1;

  /* Show image; updates current page = page
     -- also sets timer to automatically flip through images */
  this.show = function(page) {
    clearInterval(this.timer);
    this.currentPage = parseInt(page);
    $(".screenshotselector").removeClass("selected");
    $(".screenshotimg").hide();
    $("#screenshotselector" + page).addClass("selected");
    $("#screenshotimg" + page).fadeIn();

    this.timer = setInterval(function() {
      pager.next();
    }, 5000);
  };

  // Go to next image; if at the end of the list, activate first image
  this.next = function() {
    if (this.currentPage < pageCount)
      this.show(this.currentPage + 1);
    else
      this.show(1);
  };

  // Go to previous image; if at the beginning of the list, activate last image
  this.previous = function() {
    if (this.currentPage > 1)
      this.show(this.currentPage - 1);
    else
      this.show(pageCount);
  };

  // Assign click events to selection buttons and back/fwd arrows
  $(document).ready(function() {
    $(".screenshotselector").click(function(){
      var pageID = parseInt($(this).find("[name=pageid]")[0].value);

      // Don't let user click on already selected selector button
      if (pageID != pager.currentPage)
	pager.show(pageID);
    });

    $("#screenshotarrowback").click(function() {
      pager.previous();
    });

    $("#screenshotarrowfwd").click(function() {
      pager.next();
    });
  });

  this.show(1);
};


/*
  Pager to flip through videos --
  Requires a set of:  * Selection "buttons" (.videoselector -> #videoselector[1,2,3,...])
  * Images (.video -> #video[1,2,3,...])
  * Back/forward arrows -> #videoarrowback, #videoarrowfwd

  */
var VideoPager = function() {
  var pager = this;
  var pageCount = $(".video").size();

  this.currentPage = 1;

  /* Show image; updates current page = page
     -- also sets timer to automatically flip through images */
  this.show = function(page) {
    clearInterval(this.timer);
    this.currentPage = parseInt(page);
    $(".videoselector").removeClass("selected");
    $(".video").hide();
    $("#videoselector" + page).addClass("selected");
    $("#video" + page).fadeIn();

    /*this.timer = setInterval(function() {
      pager.next();
      }, 5000);*/
  };

  // Go to next image; if at the end of the list, activate first image
  this.next = function() {
    if (this.currentPage < pageCount)
      this.show(this.currentPage + 1);
    else
      this.show(1);
  };

  // Go to previous image; if at the beginning of the list, activate last image
  this.previous = function() {
    if (this.currentPage > 1)
      this.show(this.currentPage - 1);
    else
      this.show(pageCount);
  };

  // Assign click events to selection buttons and back/fwd arrows
  $(document).ready(function() {
    $(".videoselector").click(function(){
      var pageID = parseInt($(this).find("[name=pageid]")[0].value);

      // Don't let user click on already selected selector button
      if (pageID != pager.currentPage)
	pager.show(pageID);
    });

    $("#videoarrowback").click(function() {
      pager.previous();
    });

    $("#videoarrowfwd").click(function() {
      pager.next();
    });
  });

  this.show(1);
};

