_ = require 'lodash'

require './dialog.styl'

vision = angular.module 'vision'

vision.provider '$dialog', ->

  states = {}

  hash: (state, obj) ->
    obj.params = [obj.params] unless _.isArray obj.params
    obj.params = _.compact obj.params
    obj.flex ?= {}
    states[state] =
      component: obj.component
      params: obj.params
      flex: obj.flex
  $get: ($mdDialog, $location, $timeout, $rootScope) ->
    'ngInject'
    states: states
    ready: (ready) ->
      if ready? then @_ready = ready
      else return @_ready
      return
    _ready: no
    close: ->
      $location.hash null
      $mdDialog.cancel()
      @opened = no
      @component = null
      @params = {}
    # открытие окна
    opened: no
    open: (component, params, flex) ->

      # преобразуем flex в строку
      flexStr = []
      for key, val of flex
        flexStr.push "flex-#{key}=\"#{val}\""
      flexStr = flexStr.join(' ')

      # если нужно открыть то же самое - не открываем
      if _.isEqual(component, @component) and _.isEqual(params, @params)
        return false
      else
        @component = component
        @params = params
      # @ready = no
      _params = []
      locals  = {}
      url = '#'+@name
      for id, val of params
        _params.push "#{id}=\"#{id}\""
        url += '/'+val
        locals[id] = val
      _params = _params.join ' '

      elem = jQuery("[href=\"#{url}\"]")
      event = null
      if elem.length
        @from = elem
        event = jQuery.Event('click')
        event.target = elem.get(0)


      html = "<#{component} class='layout flex'
        style='position:relative' #{_params}/>"


      # unless $('#vision-dialog').length
        # открываем диалоговое окно
      $rootScope.$apply -> $mdDialog.show
        parent: document.body
        fullscreen: yes
        controller: Controller
        locals: locals
        targetEvent: event
        onRemoving: =>
          $timeout =>
            do @close unless $('#vision-dialog').length
          , 500

          # $location.hash null
        template: """
          <md-dialog #{flexStr} aria-label="Диалог" id="vision-dialog">
            <md-toolbar>
              <div class="md-toolbar-tools">
                <h2>{{dialog.title}}</h2>
                <span flex></span>
                <md-button class="md-icon-button" ng-click="close()">
                  <ng-md-icon icon="close" aria-label="Закрыть диалог">
                  </ng-md-icon>
                </md-button>
              </div>
            </md-toolbar>
            <div class='layout flex vision-dialog-content'>
              #{html}
            </div>
          </md-dialog>
        """
        # do $rootScope.$apply

      # else
      #   scope = angular.element('#vision-dialog').scope()
      #   scope.$apply => scope.render html, locals

vision.run ($dialog, $location, $timeout, $rootScope) ->
  'ngInject'
  hashchange = _.throttle ->
    hash = $location.hash()
    # console.log 'hashchange'
    if _.isEmpty hash
      do $dialog.close
      return no
    hash = hash.split '/'
    name = hash[0]
    $dialog.name = name
    if $dialog.states[name]?
      component = $dialog.states[hash[0]].component
      params = $dialog.states[hash[0]].params
      flex = $dialog.states[hash[0]].flex ? {}
      hash = hash[1..]
      _params = {}
      for param, id in params
        _params[param] = hash[id] if hash[id]?
      $dialog.component = component
      $dialog.open component, _params, flex

  , 300
  window.onhashchange = hashchange
  $timeout ->
    do hashchange
  , 500

  $(document).on 'click', '[href^="#"]', (e) ->
    do e.preventDefault
    do e.stopPropagation
    href = $(this).attr('href')
    href = href.replace '#', ''
    $rootScope.$apply ->
      $location.hash href
    # location.hash = href


  go = (to) ->
    return no unless $('#vision-dialog').length
    element = $dialog.from
    return no unless element?
    hash = element.attr('href').split('/')[0]

    # находим элемент, который повторяется
    block = element
    for i in [0..10]
      break if block.attr('ng-repeat')
      return no if i is 9
      block = block.parent()

    # находим родительский элемент
    parent = block.parents('.parent')
    parent = parent[parent.length-1]
    if parent then parent = $(parent)
    else parent = block.parent()

    block = block.next() if to is 'next'
    block = block.prev() if to is 'prev'

    # console.log block

    return no unless block.length

    # находи элемент со ссылкой
    if block.attr('href').indexOf('#')+1 then elem = block
    else elem = block.find("[href^=\"#{hash}\"]")

    return no unless elem.length

    newHash = elem.attr('href')
    $rootScope.$apply =>
      $location.hash elem.attr('href').replace('#','')
    # do hashchange

    # прокручиваем родительский блок
    setTimeout ->
      return null if elem.visible()
      pos = elem.position().top
      if pos <= 0
        parent.scrollTop(parent.scrollTop()+pos)
      else
        parent.scrollTop(parent.scrollTop()+pos-parent.height()+elem.height())
    , 100



  # при нажатии на стрелки
  $(document).on 'keydown', (e) ->

    if e.keyCode is 37
      go 'prev'
      do e.preventDefault
      do e.stopPropagation
      return no
    else if e.keyCode is 39
      go 'next'
      do e.preventDefault
      do e.stopPropagation
      return no






Controller = ($scope, $mdDialog, locals, $dialog, $location, $compile, $timeout) ->
  'ngInject'

  $scope.render = (html) ->

    # for locals

    console.log html, locals
    return no

    prevEl = angular.element('.vision-dialog-content > *')
    if not prevEl.is('.vision-loading-spinner') and prevEl.length
      prevScope = prevEl.scope()
      do prevScope.$destroy

    $scope.dialog.load = yes
    $timeout ->
      $('.vision-dialog-content').html $compile("""
        <#{component} class='layout flex'
        style='position:relative' #{params}/>
      """)($scope)
    , 100

  for id, val of locals
    $scope[id] = val
  $scope.close = -> $dialog.close()
  $scope.dialog = $dialog
  $scope.dialog.title = "Загрузка..."
  $scope.dialog.load = no
