var selectedColor = null
var strokeData = null
var lastRefresh = new Date()
var lastActive = new Date()
var timer = null

var seconds = 1000
var minutes = 60 * 1000

var lastCoords = Object()

function getSelectedColorElts() {
  return $('.selected-color')
}

function getPaletteColor(elts) {
  return elts[0].id
}

function drawPixel(elts, always) {
  var coord = elts[0].id
  if (coord.charAt(0) != '_') {
    alert("shouldn't happen")
    return
  }
  if (always || elts.attr('class') != selectedColor) {
    elts.attr('class', selectedColor)
    if (strokeData == null) {
      strokeData = [selectedColor]
    }
    strokeData.push(coord)
  }
  setActiveNow()
  unscheduleRefresh()
}

function notInStroke() {
  if (strokeData != null) {
    clearTimeout(timer)
    lastRefresh = new Date()
    var dataToSend = strokeData.join('')
    strokeData = null
    $("#pixels").load('stroke', { data: dataToSend }, function() {
      setActiveNow()
      scheduleRefresh()
    })
  } else {
    setActiveNow()
    scheduleRefresh()
  }
}

function maybeLoadPixels() {
  if (strokeData != null) {
    return
  }
  var now = new Date()
  if (now.getTime() - lastRefresh.getTime() >= 1000) {
    loadPixels()
  }
}

function loadPixels() {
  clearTimeout(timer)
  lastRefresh = new Date()
  $("#pixels").load("pixels", function() {
    lastRefresh = new Date()
  })
}

function setActiveNow() {
  lastActive = new Date()
}

function handleRefresh() {
  maybeLoadPixels()
  scheduleRefresh()
}

function scheduleRefresh() {
  unscheduleRefresh()
  if (strokeData == null) {
    var inactiveMillis = new Date().getTime() - lastActive.getTime()
    var refreshInterval = chooseRefreshInterval(inactiveMillis)
    timer = setTimeout("handleRefresh()", refreshInterval)
  }
}

function unscheduleRefresh() {
  if (timer != null) {
    clearTimeout(timer)
    timer = null
  }
}

function chooseRefreshInterval(inactiveMillis) {
  if (inactiveMillis < 2000) {
    return seconds
  } else if (inactiveMillis < 30 * seconds) {
    return 5 * seconds
  } else if (inactiveMillis < 3 * minutes) {
    return 20 * seconds
  } else if (inactiveMillis < 60 * minutes) {
    return 10 * minutes
  } else {
    return 60 * minutes
  }
}

$(document).ready(function() {

  selectedColor = getPaletteColor(getSelectedColorElts())

  $("#pixels")
      .mousedown(function(event) {
    if (event.target.tagName == 'TD') {
      drawPixel($(event.target), true)
    }
    return false
  }).mouseup(function() {
    notInStroke()
    return false
  }).mouseover(function(event) {
    if (strokeData != null) {
      if (event.target.tagName == 'TD') {
        drawPixel($(event.target), false)
      }
    } else if (event.pageX != lastCoords.x || event.pageY != lastCoords.y) {
      setActiveNow()
      maybeLoadPixels()
      scheduleRefresh()
    }
    lastCoords.x = event.pageX
    lastCoords.y = event.pageY
    event.stopPropagation()
    return false
  })


  $("#palette td")
    .click(function() {
    notInStroke()
    selectedColor = getPaletteColor($(this))
    getSelectedColorElts().removeClass("selected-color")
    $(this).addClass("selected-color")
  })

  $("#border")
    .mouseover(function() {
    notInStroke()
  })

  scheduleRefresh()
})