$ = jQuery
context = window
context.JK ||= {};


ALERT_NAMES = context.JK.ALERT_NAMES;

BackendToFrontend = {
  1 :   "CIF (352x288)",
  2 :   "VGA (640x480)",
  3 :   "4CIF (704x576)",
  4 :   "1/2 720p HD (640x360)",
  5 :   "720p HD (1280x720)",
  6 : "1080p HD (1920x1080)"
}

BackendNumericToBackendString = {
  1 :   "CIF    (352X288)",
  2 :   "VGA    (640X480)",
  3 :   "4CIF   (704X576)",
  4 :   "1/2WHD (640X360)",
  5 :   "WHD    (1280X720)",
  6 :   "FHD    (1920x1080)"
}


BackendToFrontendFPS = {

  1: 30,
  2: 24,
  3: 20,
  4: 15,
  5: 10
}

context.JK.WebcamViewer = class WebcamViewer
  constructor: (@root) ->
    @client = context.jamClient
    @logger = context.JK.logger
    @initialScan = false
    @toggleBtn = null
    @webcamSelect = null
    @resolutionSelect = null
    @videoShared = false
    @resolution = null
    @videoSettingsHelp = null
    @showBackBtn = false
    @rescanTimeout = null
    @lastDeviceList = null

  init: (@root, @showBackButton) =>
    @toggleBtn = @root.find(".webcam-test-btn")
    @webcamSelect = @root.find(".webcam-select-container select")
    @resolutionSelect = @root.find(".webcam-resolution-select-container select")
    @videoSettingsHelp = @root.find('.ftue-video-settings-help')
    @rescanningNotice = @root.find('.rescanning-notice')
    @backBtn = @root.find('.back-btn')
    @webcamSelect.on("change", @selectWebcam)
    @toggleBtn.on('click', @toggleWebcam)
    @resolutionSelect.on("change", @selectResolution)
    @backBtn.on('click', @back)
    @backBtn.show() if @showBackBtn
    #logger.debug("Initialed with (unique) select",@webcamSelect)


    context.JK.helpBubble(@videoSettingsHelp, 'ftue-video-settings', {}, {width:300}) if @videoSettingsHelp.length > 0
    @videoSettingsHelp.click(false)

  beforeShow:() =>

    @videoShared = false # video can be assumed to be closed before htis is reached
    this.loadWebCams()
    this.selectWebcam()
    this.loadResolutions()
    this.selectResolution()
    @initialScan = true
    # protect against non-video clients pointed at video-enabled server from getting into a session
    if @client.SessStopVideoSharing
      @client.SessStopVideoSharing()
    context.JK.onBackendEvent(ALERT_NAMES.USB_CONNECTED, 'webcam-viewer', @onUsbDeviceConnected);
    context.JK.onBackendEvent(ALERT_NAMES.USB_DISCONNECTED, 'webcam-viewer', @onUsbDeviceDisconnected);
    #client.SessSetInsetPosition(5)
    #client.SessSetInsetSize(1)
    #client.FTUESetAutoSelectVideoLayout(false)
    #client.SessSelectVideoDisplayLayoutGroup(1)


  onUsbDeviceConnected: () =>
    # don't handle USB events when minimized
    return if !context.jamClient.IsFrontendVisible()

    logger.debug("USB device connected");

    @scheduleRescanSystem(3000);

  onUsbDeviceDisconnected:() =>
    # don't handle USB events when minimized
    return if !context.jamClient.IsFrontendVisible()

    logger.debug("USB device disconnected");

    @scheduleRescanSystem(3000);

  scheduleRescanSystem: (time) =>
    if @rescanTimeout?
      clearTimeout(@rescanTimeout)
      @rescanTimeout = null

    @rescanningNotice.show()
    @rescanTimeout = setTimeout(() =>
      @rescanningNotice.hide()
      @loadWebCams()
    , time)

  selectWebcam:(e, data) =>
    device = @webcamSelect.val()
    if device?
      caps = @client.FTUEGetVideoCaptureDeviceCapabilities(device)
      @logger.debug("Got capabilities from device", caps, device)
      result = @client.FTUESelectVideoCaptureDevice(device, caps)
      @logger.debug("FTUESelectVideoCaptureDevice result: ", result)

  updateBackend: (captureResolution) =>
    @logger.debug 'Selecting capture resolution: ', captureResolution

    @client.FTUESetVideoEncodeResolution(captureResolution)


  selectResolution:() =>
    @logger.debug 'Selecting from res control: ', @resolutionSelect
    @resolution = @resolutionSelect.val()
    if @resolution?
      @updateBackend(@resolution)

      # if @isVideoShared
      #   this.setVideoOff()
      #   this.toggleWebcam()

  beforeHide: () =>
    if @rescanTimeout?
      clearTimeout(@rescanTimeout)
      @rescanTimeout = null

    @setVideoOff()

  setVideoOff:() =>

    if this.isVideoShared()
      @client.SessStopVideoSharing()

  isVideoShared:() =>
    @videoShared

  setToggleState:() =>
    available = @webcamSelect.find('option').size() > 0
    shared = this.isVideoShared()
    @toggleBtn.prop 'disabled', true
    @toggleBtn.prop 'disabled', !available

  back: () =>
    window.location = '/client#/account'

  toggleWebcam:() =>
    @logger.debug 'Toggling webcam from: ', this.isVideoShared(), @toggleBtn
    if this.isVideoShared()
      @toggleBtn.removeClass("selected")
      @client.SessStopVideoSharing()
      @videoShared = false
    else
      @toggleBtn.addClass("selected")
      alert("HERE?")
      @client.SessStartVideoSharing 0
      @videoShared = true

  selectedDeviceName:() =>
    webcamName="None Configured"
    # protect against non-video clients pointed at video-enabled server from getting into a session
    webcam = if @client.FTUECurrentSelectedVideoDevice? then @client.FTUECurrentSelectedVideoDevice() else null
    logger.debug("currently selected video device", webcam)
    if (webcam? && Object.keys(webcam).length>0)
      webcamName = Object.keys(webcam)[0]

    webcamName

  loadWebCams:() =>
    # protect against non-video clients pointed at video-enabled server from getting into a session
    devices = if @client.FTUEGetVideoCaptureDeviceNames? then @client.FTUEGetVideoCaptureDeviceNames() else {}
    selectedDevice = this.selectedDeviceName()
    @logger.debug("webcam devices", devices, selectedDevice)
    selectControl = @webcamSelect
    selectControl.empty()
    newDeviceList = []
    context._.each devices, (deviceName, deviceGuid) ->
      selected = deviceName == selectedDevice
      option = $('<option/>',
        id: deviceGuid
        value: deviceGuid
        text: deviceName)
      selectControl.append option

    @findChangedWebcams(devices, @lastDeviceList) if @lastDeviceList?

    @lastDeviceList = devices
    selectControl.val selectedDevice

    if devices.length == 0
      @root.find('.no-webcam-msg').removeClass 'hidden'
    else
      @root.find('.no-webcam-msg').addClass 'hidden'

  findChangedWebcams: (newList, oldList) =>
    newKeys = Object.keys(newList)
    oldKeys = Object.keys(oldList)

    @logger.debug("change webcam check", newKeys, oldKeys)
    if newKeys.length > oldKeys.length
      for newKey in newKeys
        if oldKeys.indexOf(newKey) == -1
          newWebcam = newList[newKey]
          @logger.debug("new webcam found: " + newWebcam, newKey)
          context.JK.prodBubble(@webcamSelect, 'new-webcam-found', {name: newWebcam}, {positions:['right']})
          break
    else if newKeys.length < oldKeys.length
      for oldKey in oldKeys
        if newKeys.indexOf(oldKey) == -1
          oldWebcam = oldList[oldKey]
          @logger.debug("webcam no longer found: " + oldWebcam)
          context.JK.prodBubble(@webcamSelect, 'old-webcam-lost', {name: oldWebcam}, {positions:['right']})
          break



  loadResolutions:() =>
    # protect against non-video clients pointed at video-enabled server from getting into a session
    resolutions = if @client.FTUEGetCaptureResolution? then @client.FTUEGetCaptureResolution() else {}
    selectControl = @resolutionSelect
    @logger.debug 'FOUND THESE RESOLUTIONS', resolutions
    context._.each resolutions, (resolution, resolutionKey, obj) ->

      #{1: "CIF    (352X288)", 2: "VGA    (640X480)", 3: "4CIF   (704X576)", 4: "1/2WHD (640X360)", 5: "WHD    (1280X720)", 6: "FHD    (1920x1080)"}


      frontendResolution = BackendToFrontend[resolutionKey]

      @logger.error("unknown resolution! #{resolution}") unless frontendResolution

      value = "#{resolutionKey}"
      text = "#{frontendResolution}"

      option = $('<option/>',
        value: value
        text: text)
      selectControl.append option

    # load current settings from backend
    currentResolution = @client.FTUEGetCaptureResolution()


    selected = currentResolution + '|' +  currentFrameRate

    # backend needs to be same as frontend
    if autoSelect
      @updateBackend(currentResolution, currentFrameRate)

    @logger.debug("setting current value of video settings to: " + selected)

    selectControl.val(selected)
