// Copyright 2016 The Tulsi Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Cocoa
import TulsiGenerator


@objc
protocol OptionsEditorOutlineViewDelegate: NSOutlineViewDelegate {
  /// Invoked when the delete key is pressed on the given view. Should return true if the event was
  /// fully handled, false if it should be passed up the responder chain.
  @objc optional func deleteKeyPressedForOptionsEditorOutlineView(_ view: OptionsEditorOutlineView) -> Bool
}


/// Outline view containing the options editor.
final class OptionsEditorOutlineView: NSOutlineView {
  override func keyDown(with theEvent: NSEvent) {
    guard let eventCharacters = theEvent.charactersIgnoringModifiers else {
      super.keyDown(with: theEvent)
      return
    }

    // Eat spacebar presses as the option editor view does not support activation of rows this way.
    if eventCharacters == " " {
      return
    }

    if let delegate = self.delegate as? OptionsEditorOutlineViewDelegate {
      let scalars = eventCharacters.unicodeScalars
      if scalars.count == 1 {
        let character = scalars[scalars.startIndex]
        if character == UnicodeScalar(NSDeleteCharacter) ||
            character == UnicodeScalar(NSBackspaceCharacter) ||
            character == UnicodeScalar(NSDeleteFunctionKey) ||
            character == UnicodeScalar(NSDeleteCharFunctionKey) {
          if let handled = delegate.deleteKeyPressedForOptionsEditorOutlineView?(self), handled {
            return
          }
        }
      }
    }

    super.keyDown(with: theEvent)
  }
}


/// Table cell view with the ability to draw a background.
class TextTableCellView: NSTableCellView {
  @IBInspectable var drawsBackground: Bool = false {
    didSet {
      needsDisplay = true
    }
  }

  @IBInspectable var backgroundColor: NSColor = NSColor.controlBackgroundColor {
    didSet {
      if drawsBackground {
        needsDisplay = true
      }
    }
  }

  // Whether or not this cell view is currently selected in the table.
  var selected: Bool = false {
    didSet {
      if drawsBackground {
        needsDisplay = true
      }
    }
  }

  override func draw(_ dirtyRect: NSRect) {
    if drawsBackground {
      if selected {
        NSColor.clear.setFill()
      } else {
        backgroundColor.setFill()
      }

      NSRectFill(dirtyRect)
    }
    super.draw(dirtyRect)
  }
}


/// A table cell view containing a pop up button.
final class PopUpButtonTableCellView: TextTableCellView {
  @IBOutlet weak var popUpButton: NSPopUpButton!
}


/// A text field within the editor outline view.
final class OptionsEditorTextField: NSTextField {
  override func textDidEndEditing(_ notification: Notification) {
    var notification = notification
    // If the text field completed due to a return keypress convert its movement into "other" so
    // that the keypress is not passed up the responder chain causing some other control (e.g., the
    // default button in the wizard) to handle it as well.
    if let movement = notification.userInfo?["NSTextMovement"] as? Int, movement == NSReturnTextMovement {
      let userInfo = ["NSTextMovement": NSOtherTextMovement]
      notification = Notification(name: notification.name, object: notification.object, userInfo: userInfo)
    }
    super.textDidEndEditing(notification)
  }
}


/// View controller for the multiline popup editor displayed when a user double clicks an option.
final class OptionsEditorPopoverViewController: NSViewController, NSTextFieldDelegate {
  dynamic var value: String? = nil

  enum CloseReason {
    case cancel, accept
  }
  var closeReason: CloseReason = .accept
  var optionItem: AnyObject? = nil

  fileprivate weak var popover: NSPopover? = nil

  private var optionNode: OptionsEditorNode! = nil
  private var optionLevel: OptionsEditorNode.OptionLevel = .Default

  func setRepresentedOptionNode(_ optionNode: OptionsEditorNode, level: OptionsEditorNode.OptionLevel) {
    self.optionNode = optionNode
    self.optionLevel = level
    let (currentValue, inherited) = optionNode.displayItemForOptionLevel(optionLevel)
    if inherited {
      value = ""
    } else {
      value = currentValue
    }
  }

  // MARK: - NSTextFieldDelegate

  func control(_ control: NSControl, textShouldEndEditing fieldEditor: NSText) -> Bool {
    if closeReason == .accept {
      optionNode.setDisplayItem(fieldEditor.string, forOptionLevel: optionLevel)
    }
    return true
  }

  func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
    switch commandSelector {
      // Operations that cancel.
      case #selector(NSControl.cancelOperation(_:)):
        closeReason = .cancel

      // Operations that commit the current value.
      case #selector(NSControl.insertNewline(_:)):
        closeReason = .accept
        popover?.performClose(control)
        return true

      // Operations that should be disabled.
      case #selector(NSControl.insertBacktab(_:)):
        fallthrough
      case #selector(NSControl.insertTab(_:)):
        return true

      default:
        break
    }

    // Allow the system to handle the selector.
    return false
  }
}


final class OptionsEditorController: NSObject, OptionsEditorOutlineViewDelegate, NSPopoverDelegate {
  // Storyboard identifiers.
  static let settingColumnIdentifier = "Setting"
  static let targetColumnIdentifier = OptionsEditorNode.OptionLevel.Target.rawValue
  static let projectColumnIdentifier = OptionsEditorNode.OptionLevel.Project.rawValue
  static let defaultColumnIdentifier = OptionsEditorNode.OptionLevel.Default.rawValue
  static let tableCellViewIdentifier = "TableCellView"
  static let popUpButtonCellViewIdentifier = "PopUpButtonCell"
  static let boldPopUpButtonCellViewIdentifier = "BoldPopUpButtonCell"

  // The set of column identifiers whose contents are entirely controlled via bindings set in the
  // storyboard.
  static let bindingsControlledColumns = Set([settingColumnIdentifier, defaultColumnIdentifier])

  let storyboard: NSStoryboard
  weak var view: NSOutlineView!
  // The table column used to display system or tulsiproj defaults.
  let defaultValueColumn: NSTableColumn
  // The table column used to display project-wide options.
  let projectValueColumn: NSTableColumn
  // The table column used to display build target-specific build options.
  let targetValueColumn: NSTableColumn

  dynamic var nodes = [OptionsEditorNode]()
  weak var model: OptionsEditorModelProtocol? = nil {
    didSet {
      guard let model = model else { return }
      defaultValueColumn.title = model.defaultValueColumnTitle
      projectValueColumn.title = model.projectValueColumnTitle
    }
  }

  // Popover containing a multiline editor for an option the user double clicked on.
  var popoverEditor: NSPopover! = nil
  var popoverViewController: OptionsEditorPopoverViewController! = nil

  init(view: NSOutlineView, storyboard: NSStoryboard) {
    self.view = view
    self.storyboard = storyboard
    defaultValueColumn = view.tableColumn(withIdentifier: OptionsEditorController.defaultColumnIdentifier)!
    projectValueColumn = view.tableColumn(withIdentifier: OptionsEditorController.projectColumnIdentifier)!
    targetValueColumn = view.tableColumn(withIdentifier: OptionsEditorController.targetColumnIdentifier)!
    super.init()
    self.view.delegate = self
  }

  /// Prepares the editor view to edit options with the most specialized column set to the given
  /// target rule.
  func prepareEditorForTarget(_ target: UIRuleInfo?) {
    if target == nil {
      targetValueColumn.isHidden = true
    } else {
      targetValueColumn.title = target!.targetName!
      targetValueColumn.isHidden = false
    }

    var newOptionNodes = [OptionsEditorNode]()
    var optionGroupNodes = [TulsiOptionKeyGroup: OptionsEditorGroupNode]()

    let optionSet = model?.optionSet
    guard let visibleOptions = optionSet?.allVisibleOptions else { return }
    for (key, option) in visibleOptions {
      let newNode: OptionsEditorNode
      switch option.valueType {
        case .bool:
          newNode = OptionsEditorBooleanNode(key: key, option: option, model: model, target: target)
        case .string:
          newNode = OptionsEditorStringNode(key: key, option: option, model: model, target: target)
      }

      if let (group, displayName, description) = optionSet?.groupInfoForOptionKey(key) {
        var parent: OptionsEditorGroupNode! = optionGroupNodes[group]
        if parent == nil {
          parent = OptionsEditorGroupNode(key: group,
                                          displayName: displayName,
                                          description: description)
          optionGroupNodes[group] = parent
          newOptionNodes.append(parent)
        }
        parent.addChildNode(newNode)
      } else {
        newOptionNodes.append(newNode)
      }
    }
    nodes = newOptionNodes.sorted { $0.name < $1.name }
  }

  func stringBasedControlDidCompleteEditing(_ control: NSControl) {
    let (node, modifiedLevel) = optionNodeAndLevelForControl(control)
    node.setDisplayItem(control.stringValue, forOptionLevel: modifiedLevel)
    reloadDataForEditedControl(control)
  }

  func popUpFieldDidCompleteEditing(_ button: NSPopUpButton) {
    let (node, level) = optionNodeAndLevelForControl(button)
    node.setDisplayItem(button.titleOfSelectedItem, forOptionLevel: level)
    reloadDataForEditedControl(button)
  }

  func didDoubleClickInEditorView(_ editor: NSOutlineView) {
    if editor.clickedRow < 0 || editor.clickedColumn < 0 {
      return
    }

    let clickedColumn = editor.tableColumns[editor.clickedColumn]
    let columnIdentifier = clickedColumn.identifier
    guard let optionLevel = OptionsEditorNode.OptionLevel(rawValue: columnIdentifier) else {
      assert(columnIdentifier == OptionsEditorController.settingColumnIdentifier,
             "Mismatch in storyboard column identifier and OptionLevel enum")
      return
    }
    let optionItem = editor.item(atRow: editor.clickedRow)!
    let optionNode = optionNodeForItem(optionItem as AnyObject, outlineView: editor)

    // Verify that the column is editable.
    if OptionsEditorController.bindingsControlledColumns.contains(columnIdentifier) ||
        !optionNode.editableForOptionLevel(optionLevel) {
      return
    }

    if optionNode.supportsMultilineEditor,
       let view = editor.view(atColumn: editor.clickedColumn,
                                      row: editor.clickedRow,
                                      makeIfNecessary: false) {

      popoverEditor = NSPopover()
      if popoverViewController == nil {
        popoverViewController = storyboard.instantiateController(withIdentifier: "OptionsEditorPopover") as? OptionsEditorPopoverViewController
      }
      popoverEditor.contentViewController = popoverViewController
      popoverViewController.optionItem = optionItem as AnyObject?
      popoverViewController.setRepresentedOptionNode(optionNode, level: optionLevel)
      popoverViewController.popover = popoverEditor
      popoverEditor.delegate = self
      popoverEditor.behavior = .semitransient
      popoverEditor.show(relativeTo: NSRect(), of: view, preferredEdge: .minY)
    }
  }

  // MARK: - OptionsEditorOutlineViewDelegate

  func deleteKeyPressedForOptionsEditorOutlineView(_ view: OptionsEditorOutlineView) -> Bool {
    let selectedRow = view.selectedRow
    if selectedRow < 0 || selectedRow >= nodes.count { return false }
    let selectedNode = optionNodeForItem(view.item(atRow: selectedRow)! as AnyObject, outlineView: view)
    if selectedNode.deleteMostSpecializedValue() {
      reloadDataForRow(selectedRow)
      return true
    }

    return false
  }

  func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
    if tableColumn == nil { return nil }

    let identifier = tableColumn!.identifier
    if OptionsEditorController.bindingsControlledColumns.contains(identifier) {
      return outlineView.make(withIdentifier: identifier, owner: self)
    }

    let optionNode = optionNodeForItem(item as AnyObject, outlineView: outlineView)
    let optionLevel = OptionsEditorNode.OptionLevel(rawValue: identifier)!
    let (displayItem, inherited) = optionNode.displayItemForOptionLevel(optionLevel)
    let explicit = !inherited
    let highlighted = explicit && optionLevel == optionNode.mostSpecializedOptionLevel
    let editable = optionNode.editableForOptionLevel(optionLevel)

    let view: NSView?
    switch optionNode.valueType {
      case .string:
        view = outlineView.make(withIdentifier: OptionsEditorController.tableCellViewIdentifier,
                                                  owner: self)
        if let tableCellView = view as? TextTableCellView {
          prepareTableCellView(tableCellView,
                               withValue: displayItem,
                               explicit: explicit,
                               highlighted: highlighted,
                               editable: editable)
        }

      case .bool:
        // TODO(abaire): Track down why NSPopUpButton ignores mutation to attributedTitle and remove
        //               the boldPopUpButtonCell here and from the storyboard.
        let identifier: String
        if explicit {
          identifier = OptionsEditorController.boldPopUpButtonCellViewIdentifier
        }
        else {
          identifier = OptionsEditorController.popUpButtonCellViewIdentifier
        }
        view = outlineView.make(withIdentifier: identifier, owner: self)
        if let tableCellView = view as? PopUpButtonTableCellView {
          preparePopUpButtonTableCellView(tableCellView,
                                          withMenuItems: optionNode.multiSelectItems,
                                          selectedValue: displayItem,
                                          highlighted: highlighted,
                                          editable: editable)
        }
    }
    return view
  }

  func outlineView(_ outlineView: NSOutlineView, shouldSelectItem item: Any) -> Bool {
    func setColumnsSelectedForRow(_ rowIndex: Int, selected: Bool) {
      guard rowIndex >= 0 && rowIndex < view.numberOfRows,
            let rowView = view.rowView(atRow: rowIndex, makeIfNecessary: false) else {
        return
      }
      for i in 0 ..< rowView.numberOfColumns {
        if let columnView = rowView.view(atColumn: i) as? TextTableCellView {
          columnView.selected = selected
        }
      }
    }

    setColumnsSelectedForRow(outlineView.selectedRow, selected: false)
    setColumnsSelectedForRow(view.row(forItem: item), selected: true)
    return true
  }

  // MARK: - NSPopoverDelegate

  func popoverDidClose(_ notification: Notification) {
    if notification.userInfo?[NSPopoverCloseReasonKey] as? String != NSPopoverCloseReasonStandard {
      return
    }

    if popoverViewController.closeReason == .accept {
      reloadDataForItem(popoverViewController.optionItem)
    }
    popoverEditor = nil
  }

  // MARK: - Private methods

  private func optionNodeForItem(_ item: AnyObject, outlineView: NSOutlineView) -> OptionsEditorNode {
    guard let treeNode = item as? NSTreeNode else {
      assertionFailure("Item must be an NSTreeNode")
      return nodes[0]
    }
    return treeNode.representedObject as! OptionsEditorNode
  }

  private func optionNodeAndLevelForControl(_ control: NSControl) -> (OptionsEditorNode, OptionsEditorNode.OptionLevel) {
    let item = view.item(atRow: view.row(for: control))
    let node = optionNodeForItem(item! as AnyObject, outlineView: view)
    let columnIndex = view.column(for: control)
    let columnIdentifier = view.tableColumns[columnIndex].identifier
    let level = OptionsEditorNode.OptionLevel(rawValue: columnIdentifier)!
    return (node, level)
  }

  /// Populates the given table cell view with this option's content
  private func prepareTableCellView(_ view: TextTableCellView,
                                    withValue value: String,
                                    explicit: Bool,
                                    highlighted: Bool,
                                    editable: Bool) {
    guard let textField = view.textField else { return }
    textField.isEnabled = editable

    view.drawsBackground = highlighted
    if highlighted {
      textField.textColor = NSColor.controlTextColor
    } else {
      textField.textColor = NSColor.disabledControlTextColor
    }

    let attributedValue = NSMutableAttributedString(string: value)
    attributedValue.setAttributes([NSFontAttributeName: fontForOption(explicit)],
                                  range: NSRange(location: 0, length: attributedValue.length))
    textField.attributedStringValue = attributedValue
  }

  private func preparePopUpButtonTableCellView(_ view: PopUpButtonTableCellView,
                                               withMenuItems menuItems: [String],
                                               selectedValue: String,
                                               highlighted: Bool,
                                               editable: Bool) {
    let button = view.popUpButton
    button?.removeAllItems()
    button?.addItems(withTitles: menuItems)
    button?.selectItem(withTitle: selectedValue)
    button?.isEnabled = editable
    view.drawsBackground = highlighted
  }

  private func fontForOption(_ explicit: Bool) -> NSFont {
    if explicit {
      return NSFont.boldSystemFont(ofSize: 11)
    }
    return NSFont.systemFont(ofSize: 11)
  }

  private func reloadDataForEditedControl(_ control: NSControl) {
    reloadDataForRow(view.row(for: control))
  }

  private func reloadDataForRow(_ row: Int) {
    guard row >= 0 else { return }
    let item = view.item(atRow: row)!
    reloadDataForItem(item as AnyObject?)
  }

  private func reloadDataForItem(_ item: AnyObject?) {
    let indexes = NSMutableIndexSet(index: view.row(forItem: item))
    if let parent = view.parent(forItem: item) {
      indexes.add(view.row(forItem: parent))
    } else {
      let numChildren = view.numberOfChildren(ofItem: item)
      for i in 0 ..< numChildren {
        let child = view.child(i, ofItem: item)
        let childIndex = view.row(forItem: child)
        if childIndex >= 0 {
          indexes.add(childIndex)
        }
      }
    }

    // Reload everything in the mutable middle columns. The values in the "setting" and "default"
    // columns never change.
    let columnRange = NSRange(location: 1, length: view.numberOfColumns - 2)
    view.reloadData(forRowIndexes: indexes as IndexSet, columnIndexes: IndexSet(integersIn: columnRange.toRange()!))
  }
}
