_ = require 'lodash'

module.exports =

  getInitialState: ->
    selectedItems: []
    startingPointItem:
      index: Infinity

  getSelectedItemIndex: (id) ->
    for item, index in @state.selectedItems when item.id is id
      return index

  clearSelections: ->
    @setState
      selectedItems: []

  selectItem: (item, e = {}, cb) ->
    {id, index} = item
    {startingPointItem, selectedItems} = @state
    itemIndex = @getSelectedItemIndex(id)
    state = {}

    e.preventDefault?()
    e.persist?()

    # Shift key group selections
    if e.shiftKey then return @groupSelectItems(item)

    # If no modifier, clear all other items
    unless e.metaKey or e.ctrlKey then selectedItems = []

    # Set the lowest indexed item as a starting point for shift-click group selections
    if not selectedItems.length then state.startingPointItem = item
    else if selectedItems.length and index < startingPointItem.index then state.startingPointItem = item
    
    # If the item is selected, deselect it
    if (e.metaKey or e.ctrlKey) and itemIndex > -1
      selectedItems.splice(itemIndex, 1)
      sortedSelectedItems = _.sortBy(selectedItems, 'index')

      # When removing the first item, move the starting point to the next selected item
      if index is startingPointItem.index then state.startingPointItem = sortedSelectedItems[0]
    
    # Otherwise, select the item
    else selectedItems.push(item)

    state.selectedItems = selectedItems
    @setState state
    , ->
      cb?(e.clientX, e.clientY)

  groupSelectItems: (item) ->
    {id, index} = item
    {startingPointItem, selectedItems} = @state
    records = @props.records or @records

    if startingPointItem.id?
      selectedItems = []
      selectedItems.push(startingPointItem)

      # Selections above the starting item
      if index < startingPointItem.index
        for record in records[index..startingPointItem.index] by -1 when record.id isnt startingPointItem.id
          selectedItems.push({ id: record.id, index: index, record: record })

      # Selections below the starting item
      else if index > startingPointItem.index
        for record in records[startingPointItem.index..index] when record.id isnt startingPointItem.id
          selectedItems.push({ id: record.id, index: index, record: record })

      @setState
        selectedItems: selectedItems
