Control = require('./index')

Controller      = window.require 'spine/controller'
Activateable    = window.require 'spine/controller/activateable'
Container       = window.require 'spine/controller/container'

Tabs  			= window.require 'spine/controller/tabs'
Tab 			= require '../../editor/content/tab'

Browser 		= require '../../browser/controller'
UploadBrowser = require 'Editor/content/browser/upload'

class DirectInput extends Controller
  title       : 'directinput'
  serviceTitle: 'link'
  className:'directinput directinputpopup'
  @include Activateable
  @include Container

  attributes:'authenticated':true
  containerClass:'directinput-field'
  events:
    'click .field-delete':'clear'
  constructor:(input)->
    super
    $.extend input.options,{readonly:false}
    iklass = window.require(input.control)
    @control = new iklass({attribute:@attribute,options:input.options})
    @append @control, "<span class='field-delete' data-icon='⏍'></span>"
    @control.bind "change:#{@control.type}", @onChange
    @recount = =>
    @addEntry = (i={})=>
      @control.update( i.url )
      @tab.count (v = Boolean(i.url or false))>>0
      @el.toggleClass 'old',v
    @removeEntry = (i={})=>
      @control.update('')
      @tab.count 0
      @el.toggleClass 'old',false
  clear:=>
    @control.update('');
    @onChange()

  onChange:(opts={})=>
    @tab.count((v = Boolean(opts.value or false))>>0)
    @el.toggleClass 'old',v
    @trigger 'beforeChange'
    if v
      @trigger 'urlChange',{url:opts.value,service:null}
    else
      @trigger 'urlRemove'

  release: ->
    @control.release()
    super

class BrowserPopup  extends Tabs
  className			: 'content-browser browser-popup'
  tabContainerClass 	: 'content-browser-tabs'
  containerClass 		: 'content-browser-container'

  tabRenderer 		: Tab

  @include Activateable
  interval:0

  events:
    'click .message .close' : 'closeMessage'
    'click .browser-logout' : 'deactivate'

  elements:
    '.message':              'message'
    '.message .text':        'text'

  constructor:(opts, inpt, @anchor) ->
    super
    @input = new DirectInput(inpt);
    @browsers=[]

    @input.bind 'beforeChange', @clearServices
    @input.bind 'urlChange',@contentAdd
    @input.bind 'urlRemove',@contentRemove

    delete @sources.websearch
    delete @sources.blogvio

    @$bind 'click',(e)->e.stopPropagation()
    @listenTo $('body'),'click',=>if @isActive() then @deactivate()

  children: (filter = -> true) ->
    browser for _, browser of @browsers when filter(browser)

  _initBrowsers: (popup) ->
    popup.append(@el)
    @addBrowser UploadBrowser

    for key,source of @sources
      Service  = window.require source.module
      browser = if source.browser? then (window.require source.browser) else Browser
      @browsers[key] = browser = new browser {content:[], title:key, Service:Service, options: $.extend {}, @options, source.options or {} }
      @listenTo browser, 'add', @contentAdd
      @listenTo browser, 'remove', @contentRemove
      @listenTo browser, 'canAdd', @contentCanAdd
      @append browser

    @browsers['inpt'] = @input
    @append @input

  addBrowser: (Browser) =>
    return unless Browser.isCompatible @options.types
    browser = new Browser { filetypes: @options.types }

    browser.on 'toggle', ({file, options}) =>
      @clear()
      if file.id isnt @item?.id
        item = {
          id: file.id,
          url: file.url,
          service: Browser.name
        }
        @item = item
        @trigger 'select', item
      else
        @item = null
        @trigger 'select'

    browser.observe 'selected', (selected) -> browser.tab.count selected.length
    # HACK copy the svelte css to the popup
    browser.observe(
      'loading',
      (loading) =>
        css = $('style[id^=svelte]')
        $(@popup.head).append css.clone()
      { defer: true }
    )

    updateSelected = =>
      if @item?.service is Browser.name
        browser.set({ selected: [@item.id] })
      else
        browser.set({ selected: [] })

    @on 'select', updateSelected
    updateSelected()

    @append @browsers[Browser.name] = browser

  contentAdd:(item)=>
    if item
      @item = item

    @trigger 'select', item

  contentCanAdd:(callback)=>
    @clear()
    callback?.call @

  contentRemove:(item)=>
    if @item?
      @item = null
      @trigger 'select'

  clearServices: =>
    if @item
      @browsers[@item.service]?.removeEntry?(@item)

  clear:->
    if @item
      @browsers[@item.service or 'inpt'].removeEntry?(@item)

  set:(item)=>
    @clear()
    @item = item

  deactivate: =>
    @popup?.hide()
    Activateable.deactivate.apply @,arguments

  activate:=>
    @_createPopup().then =>
      @popup.show()
      if @item
        browser = @browsers[@item.service or 'inpt']
        browser.active()
        @set(@item)
        browser.recount()
      else if @children((i)->i.isActive()).length < 1
        @children()[0].active()
      Activateable.activate.apply @,arguments

  release: ->
    @input.release()
    for _, browser of @browsers
      browser.release()
    @popup?.release()
    super

  _createPopup: ->
    return @popupPromise if @popupPromise
    @popupPromise = Blogvio.UI.popup.new
        anchor: @anchor
        topOffset: 6
        leftOffset: -9
        css: [
          'https://widgetic.com/bundles/blogvioapp/css/editor/editor.css'
        ]
      .then (@popup) =>
        @_initBrowsers @popup
        @popup.append @el
      .fail (e) ->
        console.error e.stack

class BrowserInput extends Control
  template 	: 'core/views/browser'
  className	: 'control control-browser'

  elements:
    '.input-browser': 'input'
    '.input-browser-browse': 'browseButton'

  events:
    'click .input-browser-browse, input:text, .url-thumb': 'browse'

  constructor: ->
    super

    if (input = $.extend({}, @options.input))
      input.options.readonly = true;
      iklass = window.require(input.control)
      @control = new iklass({item:@item, attribute:@attribute, options:input.options, @isDetailInput})
      @input.prepend @control.el

    if @options.browser
      @browserPopup = new BrowserPopup(@options.browser, @options.input, @browseButton)
      @browserPopup.bind 'select', @select

  update: (item,type,options={}) =>
    if item[@attribute] and options.from isnt @ and @browserPopup
      @browserPopup.set item.attrMeta?(@attribute) or item.metas?[@attribute] or {url:item[@attribute]}

  setItem: (item) =>
    super
    @control.setItem(item)

  select: (item) =>
    @change val = if item then item.url else ''
    @item.attrMeta? @attribute, if item?.service then item else null
    # atts = {}
    # atts[@attribute]= if item then item.url else ''
    # (atts.metas = $.extend {} , @item.metas)[@attribute] = if item?.service then item else null
    # @item.updateAttributes atts,{ @attribute, from:@}
    @control.$addClass('valid')
    @trigger "change:#{@type or 'control'}", {@attribute, val, value: val}

  browse: (e) =>
    e.stopPropagation()
    if @browserPopup.isActive() then @browserPopup.deactivate() else @browserPopup.activate()

  release: ->
    @control?.release()
    @browserPopup?.release()
    super

  deactivate: =>
    @browserPopup.deactivate()

module.exports = BrowserInput
