import QtQuick 2.7

import Common 1.0
import Utils 1.0

// =============================================================================

Item {
  id: searchBox

  // ---------------------------------------------------------------------------

  readonly property alias filter: searchField.text
  readonly property alias isOpen: searchBox._isOpen
  readonly property var view: _content[0]

  property alias entryHeight: menu.entryHeight
  property alias maxMenuHeight: menu.maxMenuHeight
  property alias placeholderText: searchField.placeholderText

  default property alias _content: menu._content

  property bool _isOpen: false

  // ---------------------------------------------------------------------------

  signal menuClosed
  signal menuOpened
  signal menuRequested
  signal enterPressed

  // ---------------------------------------------------------------------------

  function closeMenu () {
    if (!_isOpen) {
      return
    }

    _isOpen = false
  }

  function openMenu () {
    if (_isOpen) {
      return
    }

    _isOpen = true
  }

  function _filter (text) {
    var model = searchBox.view.model
    Utils.assert(model.setFilter != null, '`model.setFilter` must be defined.')
    model.setFilter(text)
  }

  // ---------------------------------------------------------------------------

  implicitHeight: searchField.height

  Item {
    implicitHeight: searchField.height + menu.height
    width: parent.width

    TextField {
      id: searchField

      icon: 'search'
      width: parent.width

      Keys.onEscapePressed: searchBox.closeMenu()
      Keys.onReturnPressed: {
        searchBox.enterPressed()
        searchBox.closeMenu()
      }

      onActiveFocusChanged: {
        if (activeFocus && !_isOpen) {
          searchBox.menuRequested()
          searchBox.openMenu()
        }
      }

      onTextChanged: _filter(text)
    }

    // -------------------------------------------------------------------------

    DropDownDynamicMenu {
      id: menu

      relativeTo: searchField
      relativeY: searchField.height

      // If the menu is focused, the main window loses the active status.
      // So It's necessary to map the keys events.
      Keys.forwardTo: searchField

      onClosed: searchBox.closeMenu()
    }

    Binding {
      target: searchBox.view
      property: 'width'
      value: searchField.width
    }

    Binding {
      target: searchBox.view
      property: 'headerPositioning'
      value: searchBox.view.header ? ListView.OverlayHeader : ListView.InlineFooter
    }
  }

  // ---------------------------------------------------------------------------

  states: State {
    name: 'opened'
    when: _isOpen
  }

  transitions: [
    Transition {
      from: ''
      to: 'opened'

      ScriptAction {
        script: {
          menu.open()

          searchBox.menuOpened()
        }
      }
    },

    Transition {
      from: 'opened'
      to: ''

      ScriptAction {
        script: {
          menu.close()

          searchField.focus = false
          searchField.text = ''

          searchBox.menuClosed()
        }
      }
    }
  ]
}