<commit_before>'use strict';

var m = require('mithril');
var _ = require('underscore');
var classNames = require('classnames');
var Browser = require('../browser');

// The grid UI, including the pending chip (i.e. the chip to be placed), as well
// as all chips currently placed on the grid
var GridComponent = {};

GridComponent.oninit = function (vnode) {
  var game = vnode.attrs.game;
  var state = vnode.state;
  _.extend(state, {
    // Reset/initialize the entire state of the controller
    reset: function () {
      // Current CSS position of the pending chip
      state.pendingChipX = 0;
      state.pendingChipY = 0;
      // Booleans indicating when to transition the pending chip's movement in a
      // particular direction (for example, the pending chip should never
      // transition when resetting to its initial position after placing a chip)
      state.transitionPendingChipX = false;
      state.transitionPendingChipY = false;
      // The current CSS position of the column where the user's cursor/finger
      // last clicked/touched
      state.lastVisitedColumnX = 0;
    },
    // Get the CSS translate string for the given coordinate map
    getTranslate: function (coords) {
      return 'translate(' + coords.x + 'px,' + coords.y + 'px)';
    },
    // Retrieve the constant width of a single chip
    getChipWidth: function () {
      var gridElem = document.getElementById('grid');
      return gridElem.offsetWidth / game.grid.columnCount;
    },
    // Get the index of the last visited column (the column where the cursor was
    // last at or where the last chip was dropped)
    getLastVisitedColumnIndex: function (mouseEvent) {
      var chipWidth = state.getChipWidth();
      return Math.max(0, Math.floor((mouseEvent.pageX - mouseEvent.currentTarget.offsetLeft) / chipWidth));
    },
    // Run the given callback when the next (and only the very next) pending
    // chip transition finishes
    waitForPendingChipTransitionEnd: function (callback) {
      game.emitter.off('pending-chip:transition-end');
      game.emitter.once('pending-chip:transition-end', callback);
    },
    // Horizontally align the pending chip with the specified column
    alignPendingChipWithColumn: function (args) {
      // The last visited column is the grid column nearest to the cursor at
      // any given instant; keep track of the column's X position so the next
      // pending chip can instantaneously appear there
      var newLastVisitedColumnX = state.getChipWidth(game.grid) * args.column;
      if (newLastVisitedColumnX !== state.lastVisitedColumnX) {
        state.lastVisitedColumnX = newLastVisitedColumnX;
        state.pendingChipX = state.lastVisitedColumnX;
        state.pendingChipY = 0;
        state.transitionPendingChipX = true;
        state.transitionPendingChipY = false;
        state.waitForPendingChipTransitionEnd(function () {
          state.transitionPendingChipX = false;
          // Allow the caller of alignPendingChipWithColumn() to provide an
          // arbitrary callback to run when the pending chip transition ends
          if (args.transitionEnd) {
            args.transitionEnd();
          }
        });
      }
    },
    // Align the pending chip with the column nearest to the user's cursor
    alignPendingChipViaPointer: function (mousedownEvent) {
      if (game.pendingChip && game.currentPlayer.type === 'human' && !state.transitionPendingChipY) {
        state.alignPendingChipWithColumn({
          column: state.getLastVisitedColumnIndex(mousedownEvent)
        });
      } else {
        mousedownEvent.redraw = false;
      }
    },
    // Get the coordinates of the chip slot element at the given column/row
    getSlotCoords: function (args) {
      var chipWidth = state.getChipWidth(game.grid);
      return {
        x: chipWidth * args.column,
        y: chipWidth * (game.grid.rowCount - args.row)
      };
    },
    // Place the pending chip into the specified column (or, if the chip is not
    // currently aligned with said column, do so first without placing it)
    placePendingChip: function (args) {
      var rowIndex = game.grid.getNextAvailableSlot({
        column: args.column
      });
      // Do not allow user to place chip in column that is already full
      if (rowIndex === null) {
        return;
      }
      var slotCoords = state.getSlotCoords({
        column: args.column,
        row: rowIndex
      });
      // If pending chip is not currently aligned with chosen column
      if (state.pendingChipX !== slotCoords.x) {
        // First align pending chip with column
        state.alignPendingChipWithColumn({
          column: args.column,
          // On the AI's turn, automatically place the chip after aligning it
          // with the specified column<commit_msg>Remove leftover arguments to getChipWidth()<commit_after>'use strict';

var m = require('mithril');
var _ = require('underscore');
var classNames = require('classnames');
var Browser = require('../browser');

// The grid UI, including the pending chip (i.e. the chip to be placed), as well
// as all chips currently placed on the grid
var GridComponent = {};

GridComponent.oninit = function (vnode) {
  var game = vnode.attrs.game;
  var state = vnode.state;
  _.extend(state, {
    // Reset/initialize the entire state of the controller
    reset: function () {
      // Current CSS position of the pending chip
      state.pendingChipX = 0;
      state.pendingChipY = 0;
      // Booleans indicating when to transition the pending chip's movement in a
      // particular direction (for example, the pending chip should never
      // transition when resetting to its initial position after placing a chip)
      state.transitionPendingChipX = false;
      state.transitionPendingChipY = false;
      // The current CSS position of the column where the user's cursor/finger
      // last clicked/touched
      state.lastVisitedColumnX = 0;
    },
    // Get the CSS translate string for the given coordinate map
    getTranslate: function (coords) {
      return 'translate(' + coords.x + 'px,' + coords.y + 'px)';
    },
    // Retrieve the constant width of a single chip
    getChipWidth: function () {
      var gridElem = document.getElementById('grid');
      return gridElem.offsetWidth / game.grid.columnCount;
    },
    // Get the index of the last visited column (the column where the cursor was
    // last at or where the last chip was dropped)
    getLastVisitedColumnIndex: function (mouseEvent) {
      var chipWidth = state.getChipWidth();
      return Math.max(0, Math.floor((mouseEvent.pageX - mouseEvent.currentTarget.offsetLeft) / chipWidth));
    },
    // Run the given callback when the next (and only the very next) pending
    // chip transition finishes
    waitForPendingChipTransitionEnd: function (callback) {
      game.emitter.off('pending-chip:transition-end');
      game.emitter.once('pending-chip:transition-end', callback);
    },
    // Horizontally align the pending chip with the specified column
    alignPendingChipWithColumn: function (args) {
      // The last visited column is the grid column nearest to the cursor at
      // any given instant; keep track of the column's X position so the next
      // pending chip can instantaneously appear there
      var newLastVisitedColumnX = state.getChipWidth() * args.column;
      if (newLastVisitedColumnX !== state.lastVisitedColumnX) {
        state.lastVisitedColumnX = newLastVisitedColumnX;
        state.pendingChipX = state.lastVisitedColumnX;
        state.pendingChipY = 0;
        state.transitionPendingChipX = true;
        state.transitionPendingChipY = false;
        state.waitForPendingChipTransitionEnd(function () {
          state.transitionPendingChipX = false;
          // Allow the caller of alignPendingChipWithColumn() to provide an
          // arbitrary callback to run when the pending chip transition ends
          if (args.transitionEnd) {
            args.transitionEnd();
          }
        });
      }
    },
    // Align the pending chip with the column nearest to the user's cursor
    alignPendingChipViaPointer: function (mousedownEvent) {
      if (game.pendingChip && game.currentPlayer.type === 'human' && !state.transitionPendingChipY) {
        state.alignPendingChipWithColumn({
          column: state.getLastVisitedColumnIndex(mousedownEvent)
        });
      } else {
        mousedownEvent.redraw = false;
      }
    },
    // Get the coordinates of the chip slot element at the given column/row
    getSlotCoords: function (args) {
      var chipWidth = state.getChipWidth();
      return {
        x: chipWidth * args.column,
        y: chipWidth * (game.grid.rowCount - args.row)
      };
    },
    // Place the pending chip into the specified column (or, if the chip is not
    // currently aligned with said column, do so first without placing it)
    placePendingChip: function (args) {
      var rowIndex = game.grid.getNextAvailableSlot({
        column: args.column
      });
      // Do not allow user to place chip in column that is already full
      if (rowIndex === null) {
        return;
      }
      var slotCoords = state.getSlotCoords({
        column: args.column,
        row: rowIndex
      });
      // If pending chip is not currently aligned with chosen column
      if (state.pendingChipX !== slotCoords.x) {
        // First align pending chip with column
        state.alignPendingChipWithColumn({
          column: args.column,
          // On the AI's turn, automatically place the chip after aligning it
          // with the specified column
{'fraction_non_alphanumeric': 0.0888704318936877, 'fraction_numerical': 0.0010382059800664453, 'mean_word_length': 2.706425548287803, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '336963', 'n_tokens_mistral': 2586, 'n_tokens_neox': 2520, 'n_words': 883}